First usage of WCF and specified fields.

Posted on April 27, 2009 
Filed Under .Net Code, WCF, Web Development

I hadn’t done much in the past with WCF. We had built our web service with the classes .Net 2.0 form of web services and it worked well. Then one day I realized that we had no built in security other than SSL. Since we had added a lot more things to it that could do some damage if a hacker found the service address, I decided to add some basic security. Needless to say, it’s not as easy as it looks with straight web services.

After doing some searching, I found a few examples of using WCF and implementing custom username authentication, which is exactly what I wanted to do.

Getting WCF set up and running was quite easy. Porting over our web service code just meant creating my ServiceContract and DataContracts and then recompiling. I also had to set my SQL to Linq datacontext serialization mode to Unidirectional. After coding up my custom username authentication and testing it, things were going along quite smoothly.

Everything I had experienced with Linq to SQL serialization still applied to WCF. Relationships had to have the parent set to internal access instead of public. I did also find that the relationships seemed to need a One-To-Many in order to work right. If it was a Many-To-One or a Many-To-Many, it wasn’t being sent from the WCF service to the client. Since I was in a hurry, I left that issue on the back burner and worked around it. If I five more into it, I will post about it here.

The one thing I had not counted on, was the fact that if you have any fields (properties) marked as being nullable, the Add Service wizard in Visual Studio 2008 will also add a boolean field called fieldSpecified. So if you have a nullable field for, say, PhoneNumber, you will have that and PhoneNumberSpecified. If you fill in the PhoneNumber field, but do not set PhoneNumberSpecified to true, the field will not be sent to the WCF service.

From my little bit of research, if that Specified field is set to false, the property will not be included in the XML document sent to the WCF service. If it is set to true, it will send it whether it’s null or not.

Since some of our classes have quite a few fields and we have quite a bit of code to set those fields, I did not want to go through and set every one of these stupid properties to true when I set a field. I’m actually quite surprised that we even need to do this.

In searching for an answer, I found the long way around of writing a program to parse your service.cs (or .vb) file and inserting this code:

  [System.Xml.Serialization.XmlElementAttribute(Order = 0)]
  public string PhoneNumber
  {
    get
    {
      return this.PhoneNumber;
    }
    set
    {
      this.PhoneNumber = value;
      PhoneNumberSpecified = true; // Line Added
    }
  }

So, we have to add one line to each property that has a corresponding Specified field. Now I know why people wrote a utility to do this. That file will get overwritten each time you update your service reference.

I wasn’t too pleased I had to do this so I tried to find a better way. I finally settled on using the PropertyChanged events and some reflection to go and fill that field in.

To make things simple, my Linq to SQL classes all have a base class called BaseBusiness where I do validation and hold some original values so we can use the disconnected nature of the web with Linq to SQL entities. Since I did this, I can only derive my classes on the client side from the same base class. So I created my BaseBusiness class and included my PropertyChange event in there like this:

  public partial class BaseBusiness
  {
    public void InternalPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
      if (!e.PropertyName.Contains("Specified"))
      {
        string prop = String.Format("{0}Specified", e.PropertyName);
        PropertyInfo target = this.GetType().GetProperty(prop);
        if (target != null)
        {
          PropertyInfo src = this.GetType().GetProperty(e.PropertyName);
          bool currentValue = (bool)target.GetValue(sender, null);
          bool hasValue = (src.GetValue(sender, null) == null ? false : true);
          if (currentValue != hasValue)
            target.SetValue(sender, hasValue, null);
        }
      }
    }
  }

This is pretty straight forward so far. I check to see if the field is already set to what it should be so I don’t make any unneccesary calls. Note that I use sender as the object I am using the GetValue and SetValue on. This is because the event is in a base class and wouldn’t be the right object to use for reflection since the properties would be one level up (or down, depending of where you stand).

Now the only step left is to write it up in the data classes. Which is nothing more than this:

public partial class MyDataClass : BaseBusiness
{
  public MyDataClass()
  {
    this.PropertyChanged += InternalPropertyChanged;
  }

  ~MyDataClass()
  {
    this.PropertyChanged -= InternalPropertyChanged;
  }
}

Comments

3 Responses to “First usage of WCF and specified fields.”

  1. Joe on November 27th, 2010 7:27 pm

    I’m trying to implement your idea but I think you left out a couple details. Are you implementing the INotifyPropertyChanged interface in one of these classes? Because the PropertyChanged event handler needs to be declared somewhere. How did you rig that up? Thanks.

  2. TheCodeMonk on November 27th, 2010 8:46 pm

    Joe – The only place that INotifyPropertyChanged is used is in my Linq to SQL classes. You can write them up in any custom classes, but beware, the code will only work server side. On the client side, methods and property code will not be included in the project that creates the service reference to your WCF service. They turn into dumb classes with simple properties that can be get and set.

    Think of it this way.. The classes that are public on the service are just dumb classes that you can pass data back and forth with in the service. Any custom code in those classes will not execute until that data is sent to the service and a new object is instantiated and the data is set in this object and then your property changed event can be fired.

    If I am not clear, or misunderstood, feel free to contact me via e-mail.

  3. Joe on November 27th, 2010 9:25 pm

    OK, I’m not using Linq in my project… so I’m guessing your classes are based on Linq classes which themselves implement INotifyPropertyChanged? I’m not familiar with Linq.

    I don’t know your email address so if you could shoot me an email I’d like to take this up with you further. I’d very much like to implement this functionality in my app. Thanks!

Leave a Reply