Azure tip:- WCF 4.0 ServiceRouting in Azure?

Frustrated that your ServiceRouting code doesn’t work on Azure? Forget deployment..it doesn’t even work on the development fabric??

Thanks to Christian Weyer  for pointing us in the right direction.

In order for ServiceRouting to work on Azure, a statement like

RouteTable.Routes.Add(
new ServiceRoute(
"calculate", new WebServiceHostFactory(),
typeof(CalculatorService)));

is not enough… you will also need to add the following sections to your web.config

<configSections>
    <sectionGroup name="system.serviceModel"
    type="System.ServiceModel.Configuration.ServiceModelSectionGroup, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <section name="standardEndpoints"
      type="System.ServiceModel.Configuration.StandardEndpointsSection, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
    </sectionGroup>
</configSections>

 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

and

 <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <standardEndpoints>
      <webHttpEndpoint>
        <standardEndpoint helpEnabled="true"
                          automaticFormatSelectionEnabled="true">
          <security mode="None"/>
        </standardEndpoint>
      </webHttpEndpoint>
    </standardEndpoints>
  </system.serviceModel>

so finally your web.config looks something like this

<?xml version="1.0"?>
<configuration>
  <configSections>
    <sectionGroup name="system.serviceModel"
                  type="System.ServiceModel.Configuration.ServiceModelSectionGroup, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <section name="standardEndpoints"
               type="System.ServiceModel.Configuration.StandardEndpointsSection, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
    </sectionGroup>
  </configSections>
  <system.web>
    <compilation debug="false"
                 targetFramework="4.0" />
  </system.web>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <standardEndpoints>
      <webHttpEndpoint>
        <standardEndpoint helpEnabled="true"
                          automaticFormatSelectionEnabled="true">
          <security mode="None"/>
        </standardEndpoint>
      </webHttpEndpoint>
    </standardEndpoints>
  </system.serviceModel>
</configuration>

Hope your urls look nice and pretty now!!

Cennest!!

Improving WPF/Silverlight- WCF Communication!

While working on a recent assignment related to establishing and optimizing duplex communication with Silverlight and WCF,we learnt quite a lot of new concepts like HttpPollingDuplex binding  with multiple messages mode Http Long Polling designs etc.

While most of these concepts were new we did get a bulb flash on how to improve basic WPF/Silverlight WCF communication!!

All WPF/ Silverlight applications share the same threading model . They have a UI thread and a rendering thread. The rendering thread takes care of the background processing while the UI thread takes care of painting the screen, resizing and the overall look and feel. Whatever happens on the UI thread is primarily synchronous and blocks the UI.

Now whenever we need to work with WCF services without blocking the UI we go for asynchronous calls(In Silverlight we have no option anyway), but the mistake we make is we call the WCF service directly from the UI thread(on say a button click). Now since the webmethod was called from the UI thread its Async Event Handler is also executed on the same thread. So this event handler becomes one of the many tasks the UI thread has to be performed and the end result is a slower UI update. An advantage here is that since we are on the UI thread we can update the UI element directly(else we would have to use a dispatcher!)

How else should we do this?:- An ideal way here would be to separate the task of the UI thread and disturb it only when needed i.e when we need to update the UI.

So basically use worker threads to invoke the webservices and handle their responses and use dispatchers  to update the User Interface! So the downside is slightly more complex code to finally update the UI but then you used WPF/Silverlight to get a great and responsive UI..it does come at a cost:-)

Hope this Bulb Flash helps you improve your app performance!!

Until some more flashes!

Cennest

Bulb Flash: Foreign key objects from WCF service not propagated to Silverlight client!

Consider the case :- WCF uses LINQ to SQL to connect to a DB with extensive foreign key relationships. You set Serialization Mode= Unidirectional to ensure all the relationships and DB objects can be propagated to the client as datacontracts

Silverlight client connects to the WCF service.

In many of the cases(i could not come to a rule when) i noticed that though the foreign key was accessible as an object in the WCF service, the object was not propagated to the client.

Suppose there are 3 tables called City, Company and Person. Person works in a company(foreign key), company is in a city(foreign key).

So using LINQ to SQL you would expect a relationship like Company.City (you might need to do lazy loading by using the LoadWith method with the datacontext but you will get Person.Company.City on the server)

Sometimes i noticed that though Company.City was available on the server it was not available on the client. On the silverlight client you only got Company.CityID.

Infact when i checked the dbml, Company.City was not marked as a datamember(and hence is not propagated to the client). A few suggestions on the net promoted marking it as a datamember on the dbml but then one would have to take care every time the dbml was regenerated.

So for a more permanent solution

I created a Partial class  on the WCF service itself called Company and added a property which exposed the City Property. I marked this property as a Datamember.

public partial class Company
  {
      /// <summary>
      ///     LINQ to SQL does not pass the "City" object to Silverlight 
      ///     We need the City object for processing.
      /// </summary>
      [DataMember]
      public City CompanyCity
      {
          get { return City; }
          set
          { City = value; }
      }
  }

Now the Property CompanyCity was propagated to the silverlight client and i got my City object.

Hope this bulb flash saves you a couple of hours and a few grey cells!!!

 

Cennest!

Bulb Flash: Debugging DB entity creation in Silverlight!

Your silverlight client speaks to a WCF service which in turn uses some complicated logic (say LINQ to SQL) to interact with the DB.

You create an instance of the DB object on the client side(as per User’s inputs) and send the object to the service for saving.

You are greeted with a

image 

Your object as huge and its impossible to recreate it in code , put in a windows client and debug into the webservice!!

Common scenario?? Now how do you make out what went wrong?

If you’ve faced this issue and sure you know its near impossible to debug into the WCF service from the silverlight client

Here is what i did.

  1. I implemented DataContract Serialization to save the object i want to save into an XML string.
  2. I run the application. Put a breakpoint at LoadData and save the XML string into a notepad..

using System.IO;
using System.Runtime.Serialization;
using System.IO.IsolatedStorage;

///Store the object definition in an XML String

public void StoreObject() {

using(IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
    string[] names = isf.GetFileNames("*.xml");
    if (names.Length != 0)
        foreach (string name in names)
            isf.DeleteFile(name);
    IsolatedStorageFileStream isfs = new IsolatedStorageFileStream("objectInfo.xml", FileMode.CreateNew, isf);

    StreamWriter sw = new StreamWriter(isfs);

    DataContractSerializer ser =
        new DataContractSerializer(typeof(SampleObject));
    ser.WriteObject(isfs, _currentSampleObject);
    isfs.Close();
}
string s = LoadData("objectInfo.xml");

}

///Load the stored data into an XML string

private string LoadData(string fileName)
     {
         string data;
         using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
         {

             XDocument doc = XDocument.Load(new IsolatedStorageFileStream(fileName, FileMode.Open, isf));
             data = doc.ToString();

         } return data;
     }

3. I then create a windows project and add the WCF service as the usual service reference.

4. In this windows project i add an XML file  and paste the xml string saved above into it.

5. I load the XML document in some button click and send it to the webservice.

XDocument doc =
                   XDocument.Load("XMLFile1.xml");
               client.SaveObjectFromString(doc.ToString());

6. In the Webservice i deserialize the string to get back the object i saved in step 1 and call my save function

private static void SaveObjectFromString(string objectDefinition)
       {
           DataContractSerializer ser = new DataContractSerializer(typeof(SampleObject));

           byte[] byteArray = new byte[objectDefinition.Length];
           ASCIIEncoding encoding = new
           ASCIIEncoding();
           byteArray = encoding.GetBytes(objectDefinition);

           // Load the memory stream
           MemoryStream memoryStream = new MemoryStream(byteArray);

           XmlDictionaryReader reader =
             XmlDictionaryReader.CreateTextReader(memoryStream, new XmlDictionaryReaderQuotas());

           SampleObject info =
               (SampleObject )ser.ReadObject(reader, true);

///save the created object. Same method would be getting called from the silverlight client also

SaveObjectDefinition(info);
                  }

7. Now i set the windows project as the start up project and do an f11 to debug into the webservice…

Now i know what was wrong with the object i was trying to save from my silverlight client!!

In short…

1. Use the DataContractSerializer to serialize and store your object in the isolated storage

2. Read the object into a string

3. Load it into an XML file in a windows application

4. Call the Webservice with your serialized object

5. Deserialize the object in your webservice and debug to see what the issue was!!!

Hope this Bulb flash saves you some time and a couple of grey cells!!

Cennest!!

Bulb Flash: WCF Size and Time restrictions!

While working on a Silverlight client and WCF service i hit a major roadblock when i realized that WCF has a lot of restrictions when it comes to communication. Restrictions in terms for time and  message size

The restriction is not only for size of a message but depth of message which is pretty relevant for Database entities being passed , number of elements in an array and even max length of the string incase you try DataContractSerialization

Use the following settings in your server side to overcome the time and message size restrictions to the max limit possible..

Use the following settings on your BasicHttpBinding

<basicHttpBinding>

‘For timing
<binding name=”BasicHttpBinding_XBOX” closeTimeout=”05:20:00″ openTimeout=”05:20:00″ receiveTimeout=”05:20:00″ sendTimeout=”05:20:00″

for message size

maxBufferSize=”2147483647″ maxBufferPoolSize=”2147483647″ maxReceivedMessageSize=”2147483647″ messageEncoding=”Text” textEncoding=”utf-8″ transferMode=”Buffered” useDefaultWebProxy=”true”>

<readerQuotas 
maxDepth=”2147483647″ maxStringContentLength=”2147483647″ maxArrayLength=”2147483647″
maxBytesPerRead=”2147483647″ maxNameTableCharCount=”2147483647″>

</readerQuotas>
         <security mode=”None”>
           <transport clientCredentialType=”None” proxyCredentialType=”None”
               realm=”” />
           <message clientCredentialType=”UserName” algorithmSuite=”Default” />
         </security>
       </binding>
     </basicHttpBinding>

Add the following behaviour in the service behaviour

<behavior name=”SampleServiceBehavior”>
<dataContractSerializer maxItemsInObjectGraph=”2147483646″/>

Similar settings are needed at the client app.config also.

Following snapshot shows the settings

image

If you are using Silverlight as your client then reader quotas etc are not available, but it the good news is that it reads the values from the server so it still works..

So all you need to do for Silverlight is(apart from the server side changes) make the following settings in the ServiceReferences.ClientConfig

image

Hope this marks the end of your messaging blues..Hope this bulb flash saved you some hours a grey cells!!

Cennest!!

Silverlight WCF Communication Issues!

Lets get the context straight first…i am a hardcore Microsoft person..infact i work ONLY on microsoft technologies.

But its a fact that the speed at which technology is being churned out its becoming difficult to learn how to make all different pieces work together

Although to be fair i think this article is a little late ,as the future prediction is that everyone will use Silverlight with WCF RIA services here on….but for those who may not do so(or maybe all such issues aren’t even resolved)..the next few bulb flashes will be me empathizing with those grapping with issues of making Silverlight work with WCF in a real production environment  and a few things i did to overcome them..

1. Message Size restriction

2. Debugging

3. Foreign key objects not propagated to client

4. Update Service reference issues

So read on and hope these upcoming flashes save you a couple of hours and grey cells!!

Cennest!!