BizTalk Utilities CV ,   Jobs ,   Code library
 
Go to the front page to continue learning about XML or select below:

Contents

ReBlogger Contents

Previous posts in WSCF/WCF

 
 
Page 6978 of 21350

Creating JSON-enabled WCF services in .NET 3.5

Blogger : Pluralsight Blogs
All posts : All posts by Pluralsight Blogs
Category : WSCF/WCF
Blogged date : 2008 Jan 31

Just over a year ago, I wrote an article for MSDN Magazine detailing how to make client-side web service calls with the ASP.NET Ajax extensions to .asmx web services. While most of the contents of that article still apply today to .NET 3.5 and Visual Studio 2008, there is a fundamental shift going on away from .asmx and towards .svc (WCF) for web services, so I thought it would be timely to post an update to that article to describe how to use WCF for your script-callable web services in .NET 3.5.

With .asmx Ajax services, you create a class in a .asmx file (or associated code behind file), attribute it with the [ScriptService] attribute, reference the .asmx endpoint in the Services section of your ScriptManager control on your .aspx page, and you're off and running. The new WCF Ajax-enabled service support works fundamentally the same way: parameters and results are serialized using a JSON serializer, JavaScript proxy classes are automatically generated when you reference the .svc endpoint with a /js at the end of the URL, and the invocation mechanism on the client stays the same using the familiar asynchronous callback model developers have become accustomed to with .asmx script services. The actual details of creating and referencing the service in Visual Studio 2008, however, is quite different from how .asmx script services work, and because the .asmx script service model is still in place and available, I have seen quite a few developers stick with .asmx instead of shifting their services over to .svc endpoints for familiarity. It's fine if you want to stick with .asmx endpoints, but the web service story at Microsoft is all about WCF these days, and will continue to be so in the future, so if you have already adopted the 3.5 .NET runtime, I highly recommend migrating your script web services over to the WCF model. Which brings me to the main point of this post – there has been a fair amount of confusion about how to create script-enabled WCF web services throughout the betas of 3.5, and a search on the web bring up many misleading results. My goal with this post is to provide very specific and easy to follow instructions on how to create script enabled WCF services with the final release of Visual Studio 2008 and .NET 3.5.

The simplest way to create an Ajax-enabled WCF endpoint is to use the new Visual Studio 2008 Ajax-enabled WCF Service item template. You can also script-enable an existing WCF service, but to keep this streamlined, we'll start with this template.

If you add a new service named WeatherService using this template, it will do three things for you:

  1. Create a new WeatherService.svc file that will serve as the endpoint.
  2. Create a WeatherService.cs code behind file with a class named WeatherService and a method named DoWork() ready to be implemented (or removed).
  3. Modify your web.config file to include a <system.serviceModel> section describing your new endpoint.

     

Let's start by removing the DoWork() method in WeatherService.cs and adding in a more appropriate GetForecast() method.

 

[ServiceContract(Namespace = " ")]

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

public class WeatherService

{

static Random _rand = new Random();

 

[OperationContract]

public string GetForecast(string zip)

{

switch (_rand.Next(3))

{

case 0:

return "Sunny and warm";

case 1:

return "Cold and rainy";

case 2:

return "Windy with a chance of snow";

default:

return "Invalid";

}

}

}

 

Now we're ready to call the service from script, so add a ScriptManager to the page you want to make the service call from, and add a ServiceReference to the Services element:

<asp:ScriptManager ID="ScriptManager1" runat="server">

<Services>

<asp:ServiceReference Path="~/WeatherService.svc" />

</Services>

</asp:ScriptManager>

 

Then wire up some client-side action to initiate the call – here's a sample script and piece of HTML that invokes our service:

<script type="text/javascript">

function OnGetForecast()

{

WeatherService.GetForecast($get("zip").value, OnGetForecastComplete, OnError);

}

 

function OnGetForecastComplete(result)

{

$get("weatherResult").innerText = result;

}

 

function OnError(result)

{

alert(result.get_message());

}

</script>

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

<input type="button" value="get forecast" onclick="OnGetForecast()" /><br />

<span id="weatherResult"></span>

 

So far, it feels pretty much the same, no? Things begin to feel a bit different if you begin making other changes, however. For example, let's specify a real namespace in our service definition (which was defaulted to an empty string).

 

[ServiceContract(Namespace = "http://www.pluralsight.com/ws/")]

 

This actually affects the client-side script proxy that is created – it will now be in the www.pluralsight.com.ws namespace, so we need to adjust our client script accordingly:

function OnGetForecast()

{

www.pluralsight.com.ws.WeatherService.GetForecast($get("zip").value, OnGetForecastComplete, OnError);

}

 

Note this is quite different from the way .asmx script services worked – there the class namespace was used in the client proxy, not the web service namespace. In .svc script services, the client proxy is always encapsulated in the web service namespace and the namespace of the implementation class never enters the picture. This was rather confusing in earlier releases of the WCF Ajax-enabled template which left the ServiceContract unadorned with a namespace, which meant that the web service lived in the default tempuri.org namespace. In order to reference your web services from the client side proxy, you would have to type tempuri.org.WeatherService… even though the string tempuri.org didn't show up anywhere in your code! (Keep this in mind if you ever see a script-enabled WCF service with an empty ServiceContract attribute).

Ok, the next difference you're bound to run into is also related to namespaces. If you encapsulate your web service class in a namespace (C# or VB namespace this time), you will need to make changes in both the .svc file as well as your web.config file to accommodate the name change. Let's try encapsulating our class in a namespace:

namespace Pluralsight

{

[ServiceContract(Namespace = "http://www.pluralsight.com/ws/")]

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

public class WeatherService …

}

Now we modify the WeatherService.svc file to reflect the new class (just like we would have if it were a .asmx file):

<%@ ServiceHost Language="C#"

Debug="true"

Service="Pluralsight.WeatherService"

CodeBehind="~/App_Code/WeatherService.cs" %>

And finally, we need to make two changes to the web.config which also references the class in the endpoint description:

<system.serviceModel>

...

<services>

<service name="Pluralsight.WeatherService">

<endpoint address=" " behaviorConfiguration="WeatherServiceAspNetAjaxBehavior"

binding="webHttpBinding" contract="Pluralsight.WeatherService" />

</service>

</services>

</system.serviceModel>

 

The one last thing you might find yourself missing as you migrate from .asmx-based script services to .svc script services, is the handy test page that you see when you access the .asmx endpoint directly from the browser. In fact, if you point a browser to our WeatherService.svc file, you will see a notification that "Metadata publishing for this service is currently disabled", along with a lengthy description of the configuration elements necessary to enable it. Unfortunately there is no auto-generated POST-based test page for WCF services, so you're probably best just using the JavaScript proxy to try invoking the methods as a test. There is a test client available (WcfTestClient.exe) but it is designed to work with a service that has been compiled into an assembly, so it is not easily used with the App_Code model of an ASP.NET Web site.

If you are using Web Application Projects instead of the Web site model, you will have an assembly to test your service from if you like, which may be the topic of a future post...


Read comments or post a reply to : Creating JSON-enabled WCF services in .NET 3.5
Page 6978 of 21350

Newest posts
 

    Email TopXML