DCSIMG
WCF and ASP.NET AJAX Integration - Gady Elkarif's Blog

Gady Elkarif's Blog

WCF and ASP.NET AJAX Integration

WCF and ASP.NET AJAX Integration

This post is part of WCF REST Presentation I show last week at Microsoft. 

I played with the WCF and ASP.NET AJAX integration, and created a sample web site which by can integrate WCF service with Microsoft Virtual Earth.

Virtual Earth: Starbucks Manhattan 

The Service Contract

The following contract is simple service contract with one method GetLocation(). The namespace "Sample.Services" will be used later as a prefix to the generated proxy.

AspNetCompatibilityRequirementsMode allows the service to use ASP.NET features, such as accessing HttpContext object or identity impersonation.

[ServiceContract(Namespace = "Sample.Services")]

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

public class MapService

{

    [OperationContract]

    public Location GetLocation(Target target)

    {       

        Double latitude = 0;

        Double longitude = 0;

        if (target.Name == "Starbucks Manhattan")

        {

            latitude = 40.70456;

            longitude = -74.01317;

        }

        Location location = new Location

        {

            Latitude = latitude,

            Longitude = longitude

        };

        return location;

    }

}

[DataContract]

public class Location

{

    [DataMember]

    public Double Latitude

    {

        get;

        set;

    }

    [DataMember]

    public Double Longitude

    {

        get;

        set;

    }

}

[DataContract]

public class Target

{

    [DataMember]

    public String Name

    {

        get;

        set;

    }

}

The Script

The interesting point here is how you access the service itself - by adding the namespace prefix (if not exist use default Tempuri.org).

You can also notice how I'm sending a complex parameter 'target' which is not a basic type, but complex - I use JSON directly .

var map;
var index = 0;


function LoadMap()
{   
    map = new VEMap('VEMap');
    map.LoadMap();   
}


function WebServiceCallBack(response)
{    
    AddPushPin(response);                                     
}

function AddPushPin(point)
{      
    var pin = new VEPushpin(
        index,
        new VELatLong(point.Latitude, point.Longitude),
        null,
        point.Name,
        point.Description); 
        index++;
    map.AddPushpin(pin);        
    map.PanToLatLong(new VELatLong(point.Latitude, point.Longitude));
}

function OnGetTarget()
{
    var target = { "Name" : $get("target").value }; 
    Sample.Services.MapService.GetLocation(target, WebServiceCallBack, OnError);
}

function OnError(result)
{
    alert(result.get_message());
}

Proxy Generation

Try the following URL and you will get the proxy itself:

http://localhost:49814/VirtualEarth/MapService.svc/js

Notice that the proxy created with static methods with the same signature as the methods on the service itself, and as additional, adds callback, error handler and a user context.

Type.registerNamespace('Sample.Services');
Sample.Services.MapService=function() {
Sample.Services.MapService.initializeBase(this);
this._timeout = 0;
this._userContext = null;
this._succeeded = null;
this._failed = null;
}
Sample.Services.MapService.prototype={
_get_path:function() {
var p = this.get_path();
if (p) return p;
else return Sample.Services.MapService._staticInstance.get_path();},
GetLocation:function(target,succeededCallback, failedCallback, userContext) {
return this._invoke(this._get_path(), 'GetLocation',false,{target:target},succeededCallback,failedCallback,userContext); }}
Sample.Services.MapService.registerClass('Sample.Services.MapService',Sys.Net.WebServiceProxy);
Sample.Services.MapService._staticInstance = new Sample.Services.MapService();
Sample.Services.MapService.set_path = function(value) { Sample.Services.MapService._staticInstance.set_path(value); }
Sample.Services.MapService.get_path = function() { return Sample.Services.MapService._staticInstance.get_path(); }
Sample.Services.MapService.set_timeout = function(value) { Sample.Services.MapService._staticInstance.set_timeout(value); }
Sample.Services.MapService.get_timeout = function() { return Sample.Services.MapService._staticInstance.get_timeout(); }
Sample.Services.MapService.set_defaultUserContext = function(value) { Sample.Services.MapService._staticInstance.set_defaultUserContext(value); }
Sample.Services.MapService.get_defaultUserContext = function() { return Sample.Services.MapService._staticInstance.get_defaultUserContext(); }
Sample.Services.MapService.set_defaultSucceededCallback = function(value) { Sample.Services.MapService._staticInstance.set_defaultSucceededCallback(value); }
Sample.Services.MapService.get_defaultSucceededCallback = function() { return Sample.Services.MapService._staticInstance.get_defaultSucceededCallback(); }
Sample.Services.MapService.set_defaultFailedCallback = function(value) { Sample.Services.MapService._staticInstance.set_defaultFailedCallback(value); }
Sample.Services.MapService.get_defaultFailedCallback = function() { return Sample.Services.MapService._staticInstance.get_defaultFailedCallback(); }
Sample.Services.MapService.set_path("/VirtualEarth/MapService.svc");
Sample.Services.MapService.GetLocation= function(target,onSuccess,onFailed,userContext) {Sample.Services.MapService._staticInstance.GetLocation(target,onSuccess,onFailed,userContext); }
var gtc = Sys.Net.WebServiceProxy._generateTypedConstructor;
if (typeof(Target) === 'undefined') {
var Target=gtc("Target:http://schemas.datacontract.org/2004/07/
Target.registerClass('Target');
}
if (typeof(Location) === 'undefined') {
var Location=gtc("Location:http://schemas.datacontract.org/2004/07/
Location.registerClass('Location');
}

The ASP.NET Page

<html xmlns="http://www.w3.org/1999/xhtml >
    <head id="Head1" runat="server">
        <title></title>
    </head>
    <body onload="LoadMap();">

        <form id="form1" runat="server">
            <asp:ScriptManager ID="ScriptManager1" runat="server">
                <Scripts>
                    <asp:ScriptReference Path="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=5 />
                    <asp:ScriptReference Path="mapscripts.js" />
                </Scripts>
                <Services>
                    <asp:ServiceReference Path="MapService.svc"  />
                </Services>
            </asp:ScriptManager>
            <div style='width: 800px; height: 500px; position: relative; overflow: hidden;' id='VEMap'></div>   

            Enter target: <input type="text" id="target" />

            <input type="button" value="get target" onclick="OnGetTarget()" /><br />
            <br />
        </form>
    </body>
</html>

The Service File

The WebScriptServiceHostFactory adds ASP.NET AJAX endpoint the the service, and all of this without a line of configuration!!

When you specify the WebScriptServiceHostFactory, it creates a ServiceHost with the appropriate binding and behavior for integration with ASP.NET AJAX.

<%@ ServiceHost Language="C#" Debug="true" Service="MapService" Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" %>

Conclusion

To summarize the WCF and ASP.NET AJAX Integration:

  • Full support in client stack
  • Provides proxy generation
  • Supports GET and POST only
  • Does not support UriTemplates
  • No configuration using WebScriptServiceHostFactory
  • And finally, works in ASP.NET medium trust

The source code of WCF and ASP.NET AJAX Integration.

פורסם: May 26 2008, 12:33 AM by egady | with 4 comment(s)
תגים:, , ,

תוכן התגובה

Gady Elkarif's Blog כתב/ה:

WCF 3.5 REST Presentation Hi, I want to thank to Moshe, Microsoft people and all of those who come to

# May 26, 2008 12:43 AM

DotNetKicks.com כתב/ה:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# May 26, 2008 8:45 AM

Gady Elkarif's Blog כתב/ה:

To JSON or not to JSON? I want to introduce some performance testing about DataContractJsonSerializer

# June 15, 2008 10:19 PM

David כתב/ה:

Hi mate,

Thanks for this great article. I followed the same process that you have here but when I publish my WCF service it is asking for username and password. Any idea how to fix this?

Thanks

# June 9, 2009 12:57 PM
שלח תגובה

(שדה חובה)  

(שדה חובה)  

(אופציונלי)

(שדה חובה) 

Please add 8 and 7 and type the answer here:


Enter the numbers above: