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!

Advertisements

Bulb Flash: Controls in WPF/Silverlight

Grabbed this screenshot from a Virtual Tech Day webcast. Good snapshot explanation of which control to use when

image

Hope this clears some confusion!

Cennest!!

Looking Forward to VS2010!

Few really useful developer friendly features in VS2010

1. Pin your favorite project so that its always available in the recent projects(even after a year!)

image

2. Double click a variable to highlight its usage all over the current page (no more find all references). Do a Ctrl+Shift+DownArrow to move to next reference

image

3. Do a ViewCallHierarchy to find out method dependencies

image

4. Focus on important code by collapsing rest of the code

image

Some more useful features like Datatips and export/import breakpoints to improve collaboration with other team members…more on that soon!!

Look forward to VS2010!

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!!

Migrating ASP.Net MVC 1 to ASP.Net MVC 2

With release of ASP.NET MVC 2, are you planning to migrate your ASP.Net MVC 1 applications. Here are few links which would help you to migrate

  • Eilon Lipton has created migration tool for migrating ASP.NET MVC 1 solutions to ASP.Net MVC 2 solution over here
  • To manually upgrade project  one can find instructions at www.asp.net over here

This will help you to migrate solution, but it would not leverage features of ASP.Net MVC 2. For that you will need to manually change your code.

Also after using this tool or instruction, it would be required to check if solution is able to build successfully and if building it with ASP.Net MVC 2 has lead to any logical bugs, since there are couple of breaking changes introduced in ASP.Net MVC 2

ASP.Net MVC 2 RTM Released

ASP.Net MVC 2 RTM has finally released and available on MSDN for download here

Brief on ASP.Net MVC 2 RTM

ASP.NET MVC 2 is a framework for developing highly testable and maintainable Web applications by leveraging the Model-View-Controller (MVC) pattern.

The framework encourages developers to maintain a clear separation of concerns among the responsibilities of the application – the UI logic using the view, user-input handling using the controller, and the domain logic using the model. ASP.NET MVC applications are easily testable using techniques such as test-driven development (TDD).

Comparison of ASP.Net MVC 2 RTM with ASP.Net MVC 1 RTM

ASP.Net MVC 2 RTM as compared to ASP.Net MVC 1 RTM has following additional features:

  • Support for Areas: Area feature in ASP.Net MVC 2 would allow complex application to be divided into modules.
  • Improved Security: JSONResult now supports only POST request by default.
  • Improved functionality:
    • Every property for model objects that use IDataErrorInfo to perform validation is validated, regardless of whether a new value was set
    • The UrlParmater.Optional property can be used to work around problems when binding to a model that contains an ID property when the property is absent in a form post
  • Templated Helpers: Feature from ASP.Net Dynamic Data Website in MVC for views.
  • New Validators
  • Support for binding binary data
  • Support for Asynchronous Controller Calls
  • and many more…….

I would be posting few more elaborate blog post on ASP.Net MVC 2 RTM in near future, keep watching…

Code For Keeps:- WPF/Silverlight Retrieve Images from DB/Url

WPF and Silverlight are all about images and styling and the one thing i end up doing a lot is extracting images from Databases, websites and showing them on a screen…and the code to do this is really hard to remember. So keep this code in your safe!!

1. Get Image from a byte[]: If your image is stored in the DB you will generally get it back as a binary. You can get the byte array by doing a ToArray() on the binay

public BitmapImage ImageFromBuffer(Byte[] bytes)
       {
           MemoryStream stream = new MemoryStream(bytes);
           BitmapImage image = new BitmapImage();
           image.SetSource(stream);
           stream.Close();
           return image;
       }

2. Get Image from a Url

public BitmapImage GetImageFromUrl(string imageUrl )

{

          const int BYTESTOREAD = 100000;

        WebRequest myRequest = WebRequest.Create(new Uri(imageUrl, UriKind.Absolute));
        myRequest.Timeout = -1;
        WebResponse myResponse = myRequest.GetResponse();
        Stream ReceiveStream = myResponse.GetResponseStream();
        BinaryReader br = new BinaryReader(ReceiveStream);
        MemoryStream memstream = new MemoryStream();
        byte[] bytebuffer = new byte[BYTESTOREAD];
        int BytesRead = br.Read(bytebuffer, 0, BYTESTOREAD);

        while (BytesRead > 0)
        {
            memstream.Write(bytebuffer, 0, BytesRead);
            BytesRead = br.Read(bytebuffer, 0, BYTESTOREAD);
        }
        BitmapImage image = new BitmapImage();
        image.BeginInit();
        memstream.Seek(0, SeekOrigin.Begin);

        image.StreamSource = memstream;
        image.EndInit();

        return image

     }

Hope if helps make your UI prettier!!!

Cennest!