Showing posts with label WCF. Show all posts
Showing posts with label WCF. Show all posts

Wednesday, August 24, 2011

Dreaded NotFound and Object reference not set to an instance of object exceptions in WCF RIA Services

Recently while developing an WCF RIA Services and SL4 client, I was facing these dreaded "NotFound" and "Object reference not set to an instance of object". After a bit of googling figured out the problem and its root cause.

NotFound exception

To view the actual error, you will have to use Fiddler. In the Fiddler, you can find out the actual error as "HTTP 404, Page Not Found error". This is because, WCF RIA service sits in the same virtual directory of you SL4 application. But the necessary config entries were not getting copied to the SL4 application config file.

For instance, When you create an RIA service and SL4 client; you will get the following projects in your solution;

xxxRIASerices.Host
xxxRIAServices.Host.Web

xxxSLRIAClient
xxxSLRIAClient.Web

The necessary config entries for enabling RIA service will be available in the App.Config file in xxxRIAServices.Host.Web (Basically the connectionStrings, System.Web, System.webServer sections). Copy those sections to xxxSLRIAClient.Web Web.Config file.

Bingo, we have get rid of the NotFound exception.

Object reference not set to an instance of object exception

I am sure, you will be getting this error. :) To solve this error, copy paste the System.ServiceModel section from xxxRIAServices.Host.Web App.Config to xxxSLRIAClient.Web Web.Config file.

Yes, now you should have get rid of these 2 exceptions and your WCF RIA service and SL client App will be working like charm.

Tuesday, August 23, 2011

EntityFramework and WCF

Recently while developing the WCF wrapper service for Entity Framework figured out that, the entities from EF cannot be used over the Channel. The reason was "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection". [You can capture this error if you enable WCF diagnostic logging].

There is a work around for this. You will have to use Data Transfer objects which mirror the entities from EF. So you can use those DTOs for tranmitting over the channel. It is not necessary that you will have to do this process manually, there are small add-ins available for doing this job. I used the EntitiesToDTO codeplex VS2010 add-in for this. So whenever we update the EF entities, just re-run this add-in which will update the DTOs based on the entities from EF.

PS - The transformation from entities to DTOs still need to be done by ourselves in the WCF operations.

Getting OperationContract name in WCF MessageDispatcher

There may be times where you need to identify the OperationContract name in WCF MessageDispatcher and do some processing based on that. Here is how you can do that;

In case of WCF Endpoint

In the AfterReceiveRequest method, do the following to get the Operation name;

MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);
Message originalMessage = buffer.CreateMessage();
XmlDictionaryReader xmlDict = orginialMessage.GetReaderAtBodyContents();
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlDict.ReadOuterXml());

string action = doc.DocumentElement.Name; //here you will get the OperationContract name

In case of WCF REST Endpoint

In the AfterReceiveRequest method, do the following to get the Operation name;



MessageProperties props = request.Properties;
string action = props["HttpOperationName"].ToString(); //here you will get the OperationContract name

Wednesday, July 20, 2011

WCF REST and Silverlight Synchronous calls within same domain

In my previous blog Silverlight and WCF REST near synchronous calling we saw how to achieve near synchronous behavior in the cross domain scenario. But if you have the advantage of hosting the WCF REST in the same domain of Silverlight; it is possible to achieve synchronous behavior using Wilco's HTTP requests for Silverlight

Below is the sample code which I used;
var result = Request.To("/services1.svc/DoWork")
.WithHeader("Content-Type","application/xml")
.Send().ReadAllText();

Silverlight and WCF REST, near synchronous calling

It may be very annoying since Silverlight doesn't provide synchronous calls with WCF. Loads and loads of debate happened around this but no concrete solution yet out in the market. I tried to solve this problem to an extend (not exactly synchronous) using Microsoft Rx (Reactive Extensions) framework and Wilco Bauwer's Http Request in Silverlight approach. See below how I did;


Microsoft Rx Extensions


1) Download the Microsoft Reactive Extensions framework
2) Add the System.Reactive.dll assembly reference to your Silverlight app
3) Add the following property and private variables;


private string _result;
protected bool _pageRefreshed;

public string Result1
{
get
{

return _result;
}
set
{
_result = value;
_pageRefreshed = true;
MainPage_Loaded(null, null);
}
}


Here what I am trying to do is that, instead of having the separate delegate function to handle the callback, I am pushing the callback to Silverlight Page_Loaded event. This is very similar to the way we deal with Postbacks in Page_Load in ASP.NET


4) Use this code to invoke your WCF REST service


WebClient client1 = new WebClient();
Uri url = new Uri(
https://www.WCFRESTService.Demo/BLServiceImplementation.svc/TraceError);
string input = "<LoggingServices_TraceError xmlns='http://tempuri.org/'><message>Hello!! I am from Silverlight!!!</message></LoggingServices_TraceError>";



var o = Observable.FromEventPattern(client1, "UploadStringCompleted").Select(newstring => newstring.EventArgs.Result);

o.Subscribe(s => Result1 = s);


client1.Headers["Content-Type"] = "application/xml";
client1.UploadStringAsync(url, input);


This is how it works, the result from asynchronous WCF REST call will be assigned to the Result1 property. In the Set section, after assigning to the local variable; I am also firing the Page_Loaded event of silverlight.
And in the Page_Loaded event, I am handling the result like shown below;


void MainPage_Loaded(object sender, RoutedEventArgs e)

{
if (_pageRefreshed == true)
{
_pageRefreshed = false;
result.Text = _result;
return;
}
}

Wilco Bauwer's Http Request in Silverlight approach

1) Download the code from Wilco HTTP Request and Silverlight
2) Before actually using this in you application, you need to get the code build.
3) Also, you need to make some modifications to be able to use XML and JSON WCF REST calls. Locate the Request.cs file and modify the SetRequestProperties as shown below;

private void SetRequestProperties(HttpWebRequest request) {

request.Method = _method;
foreach (var entry in _headers) {
if (entry.Key.ToLower() == "content-type")
{
request.ContentType = entry.Value;
}
else
request.Headers[entry.Key] = entry.Value;
}
}
4) Follow Step 3 in the above approach
5) Use the code below to call the WCF REST service;
Request.To(https://www.WCFREST.Demo/BLServiceImplementation.svc/TraceError)

.WithHeader("Content-Type", "application/xml")
.WithMethod("POST")
.WithBody("Hello!! I am from Silverlight!!!")
.SendAsync(response => Result1 = response.ReadAllText());

The approach is same as above except that Wilco provides Fluent Interface which is the user friendly LINQ.
The Page_Load code also same except for one small modification as below;

Dispatcher.BeginInvoke(()=> {

result.Text = _result;
});

You will make to wrap any assignment to UI controls with Dispatcher.BeginInvoke otherwise you will get cross thread access issue.

Happy coding!!! Let me know if you face any issues.

Monday, March 14, 2011

Changing WCF service reference in silverlight at runtime

Since Silverlight App is packaged as XAP file, you may be wondering how to change the service reference after building the package. It is pretty simple. XAP file is nothing but a ZIP archive file.
So,
  • Unzip the file using any ZIP archiving software
  • Locate the ServiceReferences.ClientConfig
  • Change the end point in the file, save changes
  • Zip it again and change the extension to XAP

Voila!!!

Thursday, March 10, 2011

WCF DataContract serialization and deserialization in Silverlight

Here is how you can do serialization and deserialization of WCF DataContracts in Silverlight. This is needed when you use MessageContracts in WCF by wrapping DataContracts as XmlElement.

Serialization code:

DataContractSerializer serialize = new DataContractSerializer(request.GetType());
MemoryStream stream = new MemoryStream();
serializer.WriteObject(stream,request);
string res = Encoding.UTF8.GetString(stream.ToArray(),0,stream.ToArray().GetLength(0));
TextReader reader = new StringReader(res);
XDocument doc = XDocument.Load(reader);
XElement elt = (XElement)doc.FirstNode;

you can pass the elt in your MessageContract and send to the WCF service.

Deserialization code:

Once you receive the response from WCF service as XElement, this is how you can deserialize that to object.

XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(elt.CreateReader());
DataContractSerializer serialize = new DataContractSerializer(reader);
result - serialize.ReadObject(reader);

Wednesday, March 9, 2011

Some simple steps to convert ASP.NET application to Silverlight application

Sometime you may be asked to look at the possiblity of converting the ASP.NET application to Silverlight application. Trust me, there are no hard and fast rules to migrating ASP.NET to Silverlight due to various reasons;
  1. Silverlight runs in client-side; ASP.NET runs in the server-side. This means, you will not be able to use as much as functionalities available from server-side.
  2. Application Life Cycle is entirely different for Silverlight and ASP.NET. You need to familiarize yourselves first before starting to work on silverlight.

But, somehow I managed to find some steps which will ease the ASP.NET to Silverlight migration;
  1. Find the equivalent controls for ASP.NET controls in Silverlight
  2. Convert the .aspx pages to .xaml files
  3. Define the Page navigation in App.xaml.cs file (bit difficult to do)
  4. Silverlight support very few assembly references. Migrate the .aspx.cs code .xaml.cs code accordingly.
  5. If you encounter some assembly references breaking, convert those functionalities to WCF service. Good thing about silverlight is that, it supports communication with WCF service with some limitations (no WS-Security)
  6. Silverlight follows MVVM pattern, if you application built around MVVM or can be easily upgraded to MVVM pattern, you can migrate your ASP.NET application to Silverlight application at ease...

I will update this post, If I manage to find some other tweaks and tricks in converting ASP.NET to Siliverlight.

Tuesday, February 22, 2011

Passing Default Credentials from Silverlight to WCF

While developing Silverlight and WCF apps you will have to share the default credentials from Silverlight to WCF service sometime.



This is how you can do;


1) Create the <basicHttpBinding> with the following information under the <bindings> section;

<basicHttpBinding>
<binding name="BasicBinding0">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>

2) Add the below piece of section under the <System.ServiceModel> section
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
</serviceHostingEnvironment>

3) Add the below piece of code above the OperationContract behavior;
[System.ServiceModel.Activation.AspNetCompatibilityRequirements(RequirementsMode=System.ServiceModel.Activation.AspNetCompatibilityRequirementsMode.Allowed)]
public class StaticDataProcessing : ProcessTaskWCFBase

Please note that steps 2 and 3 are needed to avoid the HttpContext.Current coming as NULL issue.

This way you can pass the default credentials from Silverlight to WCF.

Thursday, November 19, 2009

Configuring SSL for WCF services

Please follow these steps for configuring the SSL for WCF services


1.     Create and Install the Certificate on the server for Transport Security
2.     Install the Certificate on the client for Client Authentication
3.     Configure the wsHttpBinding with Certificate Authentication and Transport Security
<system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttpEndpointBinding">
          <security mode="Transport">
            <transport clientCredentialType="Certificate" />
          security>
        binding>
      wsHttpBinding>
    bindings>
    <client/>
    <services>
      <service behaviorConfiguration="ServiceBehavior"
      name="MyService">
        <endpoint binding="wsHttpBinding"
        bindingConfiguration="wsHttpEndpointBinding"
        name="wsHttpEndpoint" contract="IService" />
        <endpoint address="mex" binding="mexHttpBinding"
        contract="IMetadataExchange"/>
      service>
    services>
      system.serviceModel>
4.     Configure the mex Endpoint to Use wsHttpbinding with Certificate Authentication Configuration
<endpoint address="mex" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding"
 name="mexEndpoint" contract="IMetadataExchange" />
5.     Configure the Virtual Directory to Use SSL and require Client Certificates
a.     Open the IIS
b.    Right the website where the WCF service is hosted
c.     Select the Directory Security tab
d.    Click “Edit Secure Communications”
e.     Click “Require Secure Channel (SSL)” and click “Require Client Certificates”
Now we can open the hosted WCF service over SSL channel.

For client applications to be able to consume this service, its application configuration file should like as shown below;
<configuration>
  <system.serviceModel>
    <client>
      <endpoint
      behaviorConfiguration="ClientCertificateBehavior"
      binding="wsHttpBinding"
      bindingConfiguration="Binding1"
      contract="IMetadataExchange"
      name="https" />
    client>
    <bindings>
      <wsHttpBinding>
        <binding name="Binding1">
          <security mode="Transport">
            <transport clientCredentialType="Certificate" />
          </security>
        </binding>
      </wsHttpBinding>
    <bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="ClientCertificateBehavior">
          <clientCredentials>
            <clientCertificate findValue="CN=clienttempcert"
            storeLocation="CurrentUser"
            storeName="My"
            x509FindType="FindBySubjectDistinguishedName" />
          clientCredentials>
        behavior>
      endpointBehaviors>
    behaviors>
  system.serviceModel>
configuration>

Saturday, September 19, 2009

Accessing Active Directory information from Sharepoint

To access the information in AD like username, first name, last name, given name, CN, Role etc... from sharepoint; the following are some of the options

  • Access the Active Directory directly from the Portal
  • Create a WCF Service running under privileged user which will access the Active Directory and return the required information
  • Create Shared Service provider and use “Profile Import” technique in the sharepoint
Option 1:
This option may not be the good one since every user to the sharepoint need to have access to the corresponding Active Directory. This might not work out in case of using Windows Authentication in the sharepoint.


Option 2: (Using WCF Service)

A WCF Service can be created and make it to run under the highly privileged user who have access to Active Directory. From Portal we can make a WCF call to get the Active Directory information. The service will pull the user information from Active Directory and return back to the portal.
Pros
  •  Unlike profile import approach, the information about the user is always up-to-date since we are directly fetching the information from Active Directory.
Cons 
  • One WCF Service has to be setup to access Active Directory. Involves a little bit effort to create & deploy the WCF Service.
  •  Whenever a user logs-in a web service call has to be made to fetch the Active Directory information. This might affect the performance of the portal a little
Option 3:(Profile Import)

MOSS has the built-in technology for access the Active Directory called “Profile Import shared service”.
To use this,

  • Shared Services has to be created
  • Under “User Profiles and Properties”, “Import Connection” has to configured to the Active Directory
  • Using “Configure Profile Import” either incremental or full import has to be configured using the privileged user id and password
  • Property mappings have to be created for the information required from Active Directory
  • Then sharepoint will import all the profiles from Active Directory and store them in its SQL configuration database
  • From Portal using Elevated Privilege we will have to use “UserProfileManager” and access the user profiles.
Pros

  • The Active Directory information will be imported and stored in the configuration database of the sharepoint portal. Also, the profile information will be set in the User Context info of the logged-in user. Hence, accessing the Profile Information will have better performance than accessing the WCF Service.
  • “Profile Import” technique is in-built in sharepoint and does not involve any coding. Simple configuration settings in the “Sharepoint Central Administration” will suffice
Cons
  • The Profile Import from Active Directory will happen through schedule jobs. Hence there is a chance that the latest updated information of the user in Active Directory might not reflect immediately in the User Profile