Jakka .NET

I am Suresh Jakka, software architect at GeoCue Corp, Madison, Alabama. I have been reading serveral tech blogs and learning a lot. It is about time for me to start a blog on .NET in general so that others can learn from my experiences. Here I will be blogging about obstacles that I encounter in my day-to-day programming world and about the solutions I found.

Sunday, March 28, 2010

Using ClearUsernameBinding in Silverlight

As I told in my previous blog, I am going to explain how to use ClearUsernameBinding in Silverlight. If you just try to set the Username credentials, Silverlight framework complains about not having a secure layer. By default, it expects a secure channel for transferring the Username credentials to the server. So, we have to set the username and password token into the messages that goes from web browser to web server outside the framework of Silverlight.

All these steps have to be performed in Silverlight project.

Step1:

Define the following contstants
internal class Oasis
{
         public const string WsseNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-                                wss-wssecurity-secext-1.0.xsd";
         public const string WsseUtilityNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-                                wss-wssecurity-utility-1.0.xsd";
         public const string WsseUserNameTokenNamespace = "http://docs.oasis-   open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText";
         public const string WsseNamespacePrefix = "o";
        public const string WsseUtilityNamespacePrefix = "u";
}

Step2:
Create a UserNameSecurityTokenHeader that inherits from MessageHeader and override the following methods as shown below.

public class UserNameSecurityTokenHeader : MessageHeader
{

            protected override void OnWriteHeaderContents(System.Xml.XmlDictionaryWriter writer, MessageVersion messageVersion)
{
        writer.WriteStartElement(Constants.Oasis.WsseNamespacePrefix,
                                               Constants.UserNameToken.UserNameTokenElementName,
                                               Constants.Oasis.WsseNamespace);

        writer.WriteAttributeString(Constants.Oasis.WsseUtilityNamespacePrefix,
                                                 Constants.UserNameToken.IdAttributeName,
                                                 Constants.Oasis.WsseUtilityNamespace,
                                                 Guid.NewGuid().ToString());

        writer.WriteElementString(Constants.Oasis.WsseNamespacePrefix,
                                                Constants.UserNameToken.UserNameElementName,
                                                Constants.Oasis.WsseNamespace,
                                                this.UserName);


               /***Write Password***/

         writer.WriteStartElement(Constants.Oasis.WsseNamespacePrefix,
                                                Constants.UserNameToken.PasswordElementName,
                                                Constants.Oasis.WsseNamespace);

         writer.WriteAttributeString(Constants.Oasis.WsseNamespacePrefix,
                                                  Constants.UserNameToken.TypeAttributeName,
                                                  null,
                                                 Constants.Oasis.WsseUserNameTokenNamespace);

        writer.WriteString(this.Password);
        writer.WriteEndElement();

        /***End-Write Password***/
        writer.WriteEndElement();
}

public override string Name
{
     get { return NameValue; }
}

public override string Namespace
{
       get { return Constants.Oasis.WsseNamespace; }
}
 
Step3:
Create your custom message inspector class that implements IClientMessageInspector and override "BeforeSendRequest" method
 
public class MySilverlightMessageInspector : IClientMessageInspector
{
             public object BeforeSendRequest(ref Message request, IClientChannel channel)
            {
                      MessageHeader msgHeader = UserNameSecurityTokenHeader.FromUserNamePassword  (username, password );

                 request.Headers.Add(msgHeader);
                 return null;
           }
}
 
Step4:
Now add the above custom message inpsector to your binding.
 
That's it. Have fun coding!!!!

Friday, March 26, 2010

Better performance with "yield"

I guess, “yield” is a hidden treasure in .Net. It’s been there from .Net 2.0 but we seldom use it. It can improve the performance significantly if you are working with huge collections and returning huge collections.


If your application has to return a huge collection by reading another huge collection, it has to allocate the memory for the return collection and return it to the caller. And caller has to free that memory when it is done with it.

Here is how we do it normally.

Server method:

private static List<myobject> MyHugeList = new List();
public List GetMyHugeCollection()
{
             ListList<myobject> myReturnList = new List();
             foreach (myobject obj in MyHugeList)
            {
                 if (true) //Some condition
                 {
                        myReturnList.Add(obj);
                 }
           }
            return myReturnList;
}

Client Method:

public void MyClientMethod()
{
            int index = 0;
            foreach(object obj in GetMyHugeCollection())
           {
                  //Do some thing and return after you processed 10 object
                  if (index == 10)
                  {
                         break;
                   }
                   index++;
           }
 }

In this, couple of performance issues,

• Caller has to wait until “GetMyHugeCollection()” returns back by looping through all the members in the huge list.
• Callee (GetMyHugeCollection()) , has to allocate the memory for myReturnList (it could be significant if you are dealing with huge collections)
• Even if the caller needs a few of the items from the huge list (based on some condition), the callee has to loop through all the members in the huge list and also have to allocate the memory for the return list.

The above issues can be eliminated using “yield” and “yield break”. I will show you how to do it.

Server method:

private static ListList<myobject> MyHugeList = new List();

public IEnumerable<myobject> GetMyHugeCollection()
{
            foreach (myobject obj in MyHugeList)
           {
              if (true) //Some condition
             {
                   yield return obj;
              }
           }

          yield break;
}

Client Method:

public void MyClientMethod()
{
              int index = 0;
              foreach(object obj in GetMyHugeCollection())
              {
                      //Do some thing and return after you processed 10 object
                       if (index == 10)
                      {
                               break;
                       }
                        index++;
               }
}



In this, “GetMyHugeCollection()” method returns the first object as soon as it finds the “yield” keyword. Then caller, can process that first object immediately. Next when “foreach” at caller tries to get the second element, the callee is invoked to process where it left and returns as soon as it finds another “yield” statement. The magic is, .Net framework spits out the code to save the state of the function (callee) when it encounters “yield”. So, at runtime, it knows how to resume the callee method to get the second object. This is called delayed execution that they introduced in .Net 2.0. This concept is not new, you can achieve this by writing bunch of delegates.

The advantages of this approach are

• You do not have to allocate the memory for “MyReturnList” (no need for it) and so do not have to worry whether client frees it or not.
• Client can start processing the elements as soon as it gets the first item (a huge performance gain if you are dealing with really huge collections)
• If client needs only 10 items from the list, the callee has to loop to find only first 10 elements and no need to loop through all the elements in the huge collection.

This is little bit confusing in the beginning, but if you run a small example, you will really appreciate the power of “yield” keyword in C#.

Happy coding!!!

Monday, March 22, 2010

Changing message sizes in ClearUserNameBinding

If you want to send the Username credentials in WCF, you have to establish some kind of secure communication, like SSL. This is overkill for many of the intranet applications where we do not require that much security. Yaron Naveh wrote an excellent custom binding to be able to send the username credentials in clear text. Thank you Yaron Naveh for an oustanding custom binding. This binding uses default settings of basicHttpBinding for most of the properties like message buffer size. Here I am trying to show you how to change these values in this custom binding.

I am here setting all the values to maxium.

Step1:

In AutoSecuredHttpTransportElement() constructor, initialize the values to maximum possible

public AutoSecuredHttpTransportElement()

{
          MaxReceivedMessageSize = int.MaxValue;
         MaxBufferSize = int.MaxValue;
         MaxBufferPoolSize = long.MaxValue;
}

Step 2:

 In CreateBindingElements() method create XMLDictionaryReaderQutotas object and set the same on TextMessageEncodingBindingElement. Here is the modified version of this method.

public override BindingElementCollection CreateBindingElements()

{
         XmlDictionaryReaderQuotas rqMax = XmlDictionaryReaderQuotas.Max;
        TextMessageEncodingBindingElement textBE = new TextMessageEncodingBindingElement();
        textBE.MessageVersion = this.messageVersion;
       
       rqMax.CopyTo(textBE.ReaderQuotas);
       var res = new BindingElementCollection();
       res.Add(textBE);

       res.Add(SecurityBindingElement.CreateUserNameOverTransportBindingElement());
      res.Add(new AutoSecuredHttpTransportElement());

      return res;
}

Note: Make sure that you have "System.Runtime.Serialization" version 3.0.0.0 and above in your references. Becuase if you have version 2.0.0.0, you will get compile error as this version does not allow setting properties on ReaderQuotas.

That's it. Now your binding can receive lot more data than default one...

In my next blog, I will show you how to use this binding in Silverlight.

Have fun and happy coding...see you later...

Saturday, February 27, 2010

Deleting items while looping through the list

Anonymous delegates are very powerful in C#, especially when you are dealing with generics that can take a predicate.
How do you delete an item from the list while looping the list? One way is to collect all the items that are to be removed into another temporary collection. Next loop thru the temporary collection to remove the items from main collection…yak…


Here is a simple way.
List <strings> listStrings = new listStrings();
listStrings.Add(“tom”);
listStrings.Add(“adams”);
listStrings.Add(“jake”);
listStrings.Add(“alice”);
listStrings.Add(“john”);

//I want to remove the users that starts with “j”.
//Here is the magic…


listStrings.RemoveAll(
                                   delegate(string strRemove)
                                   {
                                              //You can put any logic here
                                              return strRemove.StartsWith(“j”);
                                   }
                                  );
//Now the resulting collection will not have “jake” and “john”…

That's it, pretty cool right?