Showing posts with label client. Show all posts
Showing posts with label client. Show all posts

Wednesday, March 28, 2012

ajax bridge

Initially, I would like to access the web services (cross-domain) in the client side only.

I watched the sample here and try to run the code. but it fails using RC
http://www.asp.net/learn/videos/view.aspx?tabid=63&id=66
error code: cant found "Samples"

I would like to ask if anyone runs the code succesfully in RC?

will there be any similar method that could archiveit and when will it be release?

thx a lot

Try to take a look at the following instructions when calling web service through javascript in the client side.
Now that we've talked about setting up the ScriptManager and how the proxy functionality works, let's take a look at how developers will leverage this technology. We'll look at passing both simple and complex data type and handling errors. During the demos, we'll take a look at the network traffic being passed to and from the server.
?
"Fire and Forget" Invocation?

If the web service class on the server includes a web method that does not return data, you can call the web service without having to handle a response. This is the simplest web method call that can be made from the client. For example, your application has the following web method:
?
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Microsoft.Web.Script.Services.ScriptService]
public class Parts : System.Web.Services.WebService
{
[WebMethod]
public void NoReturn()
{
//do work here
System.Threading.Thread.Sleep(2000);
}
}
?
The following JavaScript can be used to invoke that web method
?
function RunWebService()
{
Parts.NoReturn();
}
?
If the webservice is in a custom namespace, you would need to fully
qualify the call to the webservice. For example, if the WebService
has a namespace of MyCustomNameSpace.WebServices, the above JavaScript
becomes:
?
function RunWebService()
{
MyCustomNameSpace.WebServices.Parts.NoReturn();
}
?
Getting a return value?
In a scenario where the web method has a return value, then the asynchronous invocation model requires providing a callback function that will be called when the web service call returns. The callback function has an input parameter that contains the results of the web service call.
?
The server-side AJAX stack will appropriately serialize the return value from the web method, and the client-side AJAX stack will deserialize the data to an appropriate JavaScript type to be passed to the callback function.
?
On the Server-side, there is a WebMethod that returns a string:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Microsoft.Web.Script.Services.ScriptService]
public class Parts : System.Web.Services.WebService
{
[WebMethod]
public string DynamicDropdown()
{
string tmpDropDown;
tmpDropDown = "<select id=test name=test><option value=Part1>Part1</option><option value=Part2>Part2</option></select>";
return tmpDropDown;
}
}
?
When you call the web service in client script, the call will need to have a callback function specified to handle the return value. The following script demonstrates calling the DynamicDropdown WebMethod of the Parts Web Service and specifies OnComplete as the callback function. The OnComplete function has an input paramter which is the return object from the web service call, in this case, this will be the string value. The OnComplete function then takes the return value and inserts it as the innerHTML property of a span with ID DynamicArea. The result is that a dropdown appears on the page.
function InsertDropdown()
{
Parts.DynamicDropdown(OnComplete);
return false;
}
function OnComplete(result)
{
DynamicArea.innerHTML += result;
}
Passing primitive type parameters to web method
If the web method takes input parameters, then the JavaScript invocation of the method will take corresponding JavaScript parameters. The parameter values will be serialized by the AJAX stack into JSON and packaged in the body of the request and then de-serialized as .Net types corresponding to the signature of the web method.
?
For example, given the following server method that accepts a string parameter and returns a string:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Microsoft.Web.Script.Services.ScriptService]
public class Parts : System.Web.Services.WebService
{
[WebMethod]
public string EchoString(String s)
{
return s;
}
}
?
You would use the following JavaScript to call the web service, pass the string parameter and include the callback function:
?
function CallEchoString()
{
Parts.EchoString(form1.GetString.value, OnCallBack);
}
function OnCallBack(results)
{
alert(results);
}
?
The call to the EchoString web method on the Parts.asmx web service is taking the value from a textbox named GetString in a form with ID of "form1" to pass as the input parameter and specifying OnCallBack as the callback function. The OnCallBack function has an input parameter of "results" which is the return type from the EchoString web method. The JavaScript then displays that in a popup box.
Specifying a callback for failure cases?
If the request to the web method is unsuccessful, whether because of error, timeout, or if server code aborts the request, then the callback specified for successful completion will not be called. A second callback function can be specified in the call to the web service for failure cases, receiving an error object as parameter, as in the following javascript:
?
function CallService()
{
PeopleServices.ThrowError(OnCallBackThrowError, OnError);
}
function OnCallBackThrowError(result)
{
alert("OnCallbackThrowError: " + result);
}
function OnError(result)
{
alert("OnError: " + result.get_message());
alert(result.get_stackTrace());
}
?
In the code sample, the ThrowError method of the PeopleServices web service does not take any input parameters. The method call passes the callback function "OnCallBackThrowError" and a method for handling any error condition called "OnError". The OnError method takes an input parameter which is a error object that contains the error message and stack information passed from the server if a .NET Exception was thrown. In this case, the information is displayed in popup windows, but once you have the errors in the browser, you can notify the user in any manner you feel is appropriate.
Using the same callback from multiple callers?
You can leverage the same callback function on the client for multiple web service calls. This allows you to avoid having to write a client function for each callback. In order to differentiate the calls, you pass a user context object that contains information that can be used to tell the requests apart. The user context object can be any JavaScript primitive type, array, or object.
?
For example, let's say you have a web service that contains a web method that you need to call multiple times from the client. You need to know which response corresponds to each call. For example, the first call's return value is placed in Span1 and the second call is in Span2. In order to do this, you can associate context information with the request and you can use the context information to distinguish which request is providing the response. This information is not passed to the server by default. If you want to pass this information to the web service, you would need to pass it as an input parameter to the remote method.
?
On the server, you have the following web service method that is taking in the a string which should be a stock symbol and returning a string:
?
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Microsoft.Web.Script.Services.ScriptService]
public class Parts : System.Web.Services.WebService
{
[WebMethod]
public string UserContextSample(string stockSymbol)
{
string returnValue = String.Empty;
//do work here to look up stock symbol info
return returnValue;
}
}
?
On the client, you create a JavaScript object to store context specific information and pass that as the last parameter to the web service call. In the sample below, we're creating a dictionary object on the client with a key of contextKey and a value of a stock quote. The syntax for the web service call is:
?
WebService.Method(InputParams, CallBackMethod, ErrorMethod, contextInfo);
?
function CallServicesTest()
{
var userContext1 = {contextKey:"MSFT"};
Parts.UserContextSample("MSFT", OnCallBack, OnError, userContext1);
var userContext2 = {contextKey:"AAPL"};
Parts.UserContextSample("AAPL", OnCallBack, OnError, userContext2);
}
In the callback function, you add a second input parameter that contains the context passed in the web service call. This way you get the results of the web service call in the first input parameter and the context information in the second parameter. In this case, we're checking the context information and inserting text into specific spans on the page along with the response from the web service.
?
function OnCallBack(results, userContext)
{
switch(userContext.contextKey)
{
case "MSFT":
SPAN1.innerHTML = "Microsoft " + results;
break;
case "AAPL":
SPAN2.innerHTML = "Apple " + results;
break;
}
}
Using the same callback for different web methods?
This scenario is similar to using the same callback for multiple calls with the exception that you have two separate web service methods on the client that are using the same callback method. In this scenario, you include a third input parameter on the callback function to receive the web service call that the response is associated to.
?
For example, you have two Web Methods that your function needs to call, but you want to have a single callback method. You can tell which web method is returning by accessing the optional third input parameter to the callback function.
?
On the server you have:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Microsoft.Web.Script.Services.ScriptService]
public class Parts : System.Web.Services.WebService
{
[WebMethod]
public string EchoString(String s)
{
return s;
}
[WebMethod]
public string AnotherEchoString(String s)
{
return s;
}
}
?
On the client you have a button that has an onclick method calling GetEcho() function in JavaScript:
?
function GetEcho()
{
Parts.EchoString("This is echo number 1", OnCallBack);
Parts.AnotherEchoString("Another echo string!", OnCallBack);
}
function OnCallBack(results, userContext, sender)
{
alert(results + "\n" + sender);
}
?
When OnCallBack runs, you will get an alert dialog with the string you passed to the web service along with Parts.EchoString or Parts.AnotherEchoString.
Passing and receiving a server type?
As mentioned previously, the AJAX networking stack will generate proxy scripts for any server type that is referenced as an input or output parameter by the web methods contained in linked web services. This allows a developer to access these types on the client in a similar fashion as they would on the server. The types are serialized using JSON serialization which is covered in the next lesson.
?
For example, let's say you have the following web service called PeopleServices. This web service has a method called NewPerson that takes in 3 parameters; 2 Person objects and 1 object of type bool. The return value is also of type Person.
?
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Microsoft.Web.Script.Services.ScriptService]
public class PeopleServices : System.Web.Services.WebService
{
?
[WebMethod]
public Person NewPerson(Person parent1, Person parent2, bool female)
{
Person _newPerson = new Person();
//Do other work
return _newPerson;
}
}
When you add this web service to the ScriptManager, the client will make a request for the proxy script as discussed in the Proxy Generation section. The result is that the Proxy script will have the web service method as well as the properties for the Person class. The person class is defined as the following on the server:
?
public class Person
{
public string Name
{
get { return _name; }
set { _name = value; }
}
public int Age
{
get { return _age; }
set { _age = value; }
}
public int Height
{
get { return _height; }
set { _height = value; }
}
}
?
On the client, you would need to generate two objects of type Person and pass them as parameters to the web service. In the callback script, the result parameter will be of type Person. Here's a sample JavaScript function that takes the values of textboxes on the page and creates two Person objects, then calls the NewPerson object on the above web service.
?
function GetNewPerson()
{
var person1 = new Person();
var _name = document.getElementById('p1FirstName');
var _age = document.getElementById('p1Age');
var _height = document.getElementById('p1Height');
person1.Name = _name.value;
person1.Age = _age.value;
person1.Height = _height.value;
?
var person2 = new Person();
_name = document.getElementById('p2FirstName');
_age = document.getElementById('p2Age');
_height = document.getElementById('p2Height');
?
person2.Name = _name.value;
person2.Age = _age.value;
person2.Height = _height.value;
PeopleServices.NewPerson(person1, person2, true, OnCallbackGetNewPerson, OnError);
}
?
Here is a sample callback function that handles the return type from the NewPerson method. The result parameter is a Person object and you can directly access the properties. In this case NewPerson is the ID on a Div in the page.
?
function OnCallbackGetNewPerson(result)
{
var newPerson = result;
NewPerson.innerHTML = "New Person <br/>";
NewPerson.innerHTML += "Name: " + newPerson.Name + "<br />";
NewPerson.innerHTML += "Age: " + newPerson.Age + "<br />";
NewPerson.innerHTML += "Height: " + newPerson.Height + "<br />";
}
When you run pages that make these calls and check out the network traffic, you'll see the following:
Web service call is a POST to …/PeopleService.asmx/js/NewPerson. Since the request ends in /js/NewPerson, the AJAX HttpHandler will handle the request to the web service. The Content-Type of the request is application/json.
Request Body contains all the data to create the Person object on the server. The main piece is the __type parameter which tells the server what type to create:
?
{"parent1":{"__type":"Person","Name":"Name1","Age":"12","Height":"60"},"parent2":{"__type":"Person","Name":"Name2","Age":"24","Height":"72"},"female":true}
The response also has a Content-Type of application/json and has a similar body containing the __type parameter and values necessary to create the Person object on the client:
?
{"__type":"Person","Name":"Name1name2ella","Age":23,"Height":71}
?Demo is FireForgetDemo.aspx
?
Wish the above can help you.

AJAX Behaviours -- documentation

Hi!

Can someone please point me to the a place, where Behaviours are explained? I found that some controls have custom behaviours and I found a client side Behaviours class.

I'd like to modify the onkeypress handler of a asp:TextBox control -- is Behaviour the right place to do so?

Thanks,

Miha.

mihav:

Hi!

Can someone please point me to the a place, where Behaviours are explained? I found that some controls have custom behaviours and I found a client side Behaviours class.

It is covered in the docs and explained with code by long time AJAX user Garbin. Hope this helps.

http://ajax.asp.net/docs/ClientReference/Sys.UI/BehaviorClass/default.aspx

http://aspadvice.com/blogs/garbin/archive/2006/01/23/14786.aspx


Thanks. The Garbin's post looks helpful -- the Behaviour class documentation is useless (I found that before) in helping understand what Behavirours are all about.

I'd like to change the the onkeypress event handling of the TextBox control to do a postback on every keypress... I hope behaviours are the right direction to go to?

Thanks,

Miha.


What you want is easier with JavaScript per the thread below, if you choose to use AJAX search Garbin's blog for all related posts and modify the code as needed. Hope this helps.

http://forums.asp.net/thread/1348454.aspx


Thanks. I pretty much solved the problem with "ordinary" input type=textbox field and a javascript event handler. I did find out, though, that if I remove the <asp:TextBox> from the page (although I am not using it) the __doPostback updates the whole page, not just the UpdatePanel content. To explain better:

Page has an ordinary text box andasp:TextBox on it. Both text boxes are outside of the update panel. Within an Update panel, there is a AsyncPostBackTrigger, referring to asp:TextBox control (which I amnot using). When I use the ordinary text box, everything works (meaning that the updates only affect update panel). So, if I remove the AsyncPostBackTrigger, the __doPostBack, triggered by ordinary textbox updates the whole page. If I try to wire AsyncPostBackTrigger with ordinary textbox, I get an error

A control with ID 'SearchBox' could not be found for the trigger in UpdatePanel 'UpdatePanel1'.
Because there is no control. (it is just markup...).  Is there a way to wire ordinary form field (not asp.net control) with updatepanel?
Miha 


hello.

Triggers are only meant to be used with server side controls. if you have a regular HTML control which starts a postback, then you can try to add the client id of that control to the _asyncPostbackControlsIDs collection maintained by the pagerequestmanager object.


Luis, can you please help me with _asyncPostbackControlsIds collection? Where do I find it? The PageRequestManager does not seem to have it. I've put a script block at the end of the aspx file and I got an undefined value for _asyncPostbackControlsIds.

Aha, I found out it is a typo. But nontheless, the code doesn't work. There must be another way to register this HTML control with pagerequest manager object. The code I tried is:

 var prm = Sys.WebForms.PageRequestManager.getInstance(); prm._asyncPostBackControlIDs.add('SearchBox');
Thanks, Miha.

Sorry. I'm a bit rusty with javascript.

So, I added it to the array.

If I remove the trigger <asp:AsyncPostBackTrigger ControlID="SearchBoxx" EventName="TextChanged" /> from the <triggers> in aspx, the array size decreases to 0, and is 1 after I add the 'SearchBox' HTML control to it. It still doesnot work, because it now refreshes the whole page again. There is something missing to this story. Something to tell the pagerequest manager to only update the updatepanel? The markup generated for the textboxes isidentical in both cases. The only difference on the page is this:

Sys.WebForms.PageRequestManager.getInstance()._updateControls(['tUpdatePanel1'], ['SearchBoxx'], [], 90);

When there is no <trigger> present, the second parameter is empty. And I tried to add that to a script at the end of the ASPX file, but it still refreshes the whole page...

Aaaaa. I would really like to get rid of the asp:TextBox control, as it is doing nothing on the page...

Miha


hello.

try running this:

<%@. Page Language="C#" AutoEventWireup="true" %>
<script runat="server">
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);

if (ScriptManager1.IsInAsyncPostBack &&
Request.Params["__EVENTTARGET"] == "txt")
{
panel.Update();
}
}
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Untitled Page</title>
<script>
function main()
{
// Add Client Code here
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">

</asp:ScriptManager
<asp:updatepanel runat="server" id="panel" UpdateMode="Conditional">
<ContentTemplate>
panel 1:
<%= DateTime.Now.ToString() %>
</ContentTemplate>
</asp:updatepanel>

<asp:updatepanel runat="server" id="Updatepanel1" UpdateMode="Conditional">
<ContentTemplate>
panel 2:
<%= DateTime.Now.ToString() %>
</ContentTemplate>
</asp:updatepanel>

<input type="text" id="txt" onchange="__doPostBack('txt','');"; />
</form>
<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded( function() {
Sys.WebForms.PageRequestManager.getInstance()._asyncPostBackControlClientIDs.push( "txt" );} );
</script>
</body>
</html>


Luis, this is excellent. It works. I'll see what changes I have to make to make my example work and I'll post the solution to my problem (should someone else have the same problem).

Tnx,

Miha.


3 months later, and out of AJAX RC, the solution to this problem was this:

Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded( function() {
Sys.WebForms.PageRequestManager.getInstance()._asyncPostBackControlClientIDs.push( "txt" );} );

Thanks again,

Miha.

Monday, March 26, 2012

AJAX asynchronous calls without update panel

Is the UpdatePanel always needed to make Asynchronously calls to the server? I was catching up with the client side capabilities for the framework using the $get and $sys client classes and seem to provide a lot of functionality. Any samples, tutorials where I can go to get some reference. I went through the AJAX framwework documentation but no help.

No, you can also use webservices or pagemethods take a look at these links:

http://www.asp.net/ajax/documentation/live/overview/AsynchronousLayerOverview.aspx

http://www.asp.net/ajax/documentation/live/tutorials/ExposingWebServicesToAJAXTutorial.aspx

http://www.asp.net/ajax/documentation/live/tutorials/ConsumingWebServicesWithAJAXTutorial.aspx

Hope this helps,
Elias.

Saturday, March 24, 2012

Ajax and Session when WebServices called from client site

I have been trying to find a solution for session state and AJAX web service calls. I have a simple page that reports different session id than the web service called from AJAX client site. There are lots of discussions of this topic but no real answers.

Am I lost? Is it that each web service calls from the client site are associated always different session?

How can I limit the web services to be called from client when they don't have session in server?

Or is this something I have to do by using the AJAX authentication services?

What about if webservice needs to access the session state variables how this can be accomplished as they have different session ids?

Regards,

Alexander

A unique session ID and a session object is not associated with a session until a session variable is added to the Session. You should assign to and create at least one session variable like following:

Session["__Dummy"] = "Some Value";

After you do this the session Id will remain constant for the session.


Yes, that was the magic... solved my problem.

Thanks...