May 2007 - Posts
I have tried to avoid regurgitating information that has already been circulating the blogosphere. However, I am going to break that rule today because the topic is just too damn cool! Yesterday, Microsoft announced a new product known as Surface. If you haven't heard about it, do yourself a favor and visit the site right now! I mean now! Stop reading this and go do it, but be sure to watch the videos!
All I can say is WOW!
I read where Scott Guthrie mentioned another very interesting tidbit of information. Surface actually uses WPF and the .NET Framework to deliver the table UI experience. How awesome is that?
It is a very cool concept, and some of the videos on the site really drive home the potential of what this thing can do. I had read about this concept in the past, but I had no idea it was this close to actually being marketable. At any rate, I really see a lot of possibilities for the product. Imagine sitting down to play a game with your friends by interacting with the coffee table! Sign me up!
Here is an article on Popular Mechanics that covers more information about the design of the device.
Yesterday, I delivered a WCF presentation for a Microsoft Developer Day event in Nashville, TN. It was held at the Tennessee Tower, and most of the attendees were IT employees for the State of Tennessee. The entire event was basically a good introduction of .NET 3.0 and also touched on MOSS 2007. I really enjoyed this particular speaking event. The crowd was very attentive and interactive. There seemed to be a lot of genuine enthusiasm about .NET 3.0 and its possibilities.
Overall, I feel like my WCF presentation went fairly well. Several folks expressed an interest in getting access to the slides and code. So, I thought I would oblige.
Here is a link to the RAR file that contains my slides and code demos used during the presentation. If you have any questions, please feel free to email me or use the contact form on my blog. I am always happy to discuss WCF!
Last week, Keith Elder mentioned that he signed up for a Twitter account. After reading a few of his updates, I decided to give it a try. So, I signed up for an account as well.
I have been signed up for four days and managed to post four updates. It is an intriguing concept, but I can easily see how it becomes more work than fun. For now, I will continue giving it a try, but I'm not sure it will last long term.
If it sounds interesting, I would encourage you to sign up and give it a try. Feel free to add me on your friends. My handle is jeff_barnes.
It is my first day back on the job after returning from vacation. I am still attempting to get my mind back on track from staring at the ocean for a week. So, I am taking it easy on blogging tonight and will kick it back to Mr. Wally McClure.
He recently blogged about a topic that was stirred up about the time I left for vacation. As such, I never really had a chance to throw in my two cents. It all started when an article appeared on Information Week asking "Why Doesn't Microsoft Have a Cult Religion?". The same issue was raised by Mary Jo Foley in her post entitled "Could Microsoft take a community lesson from Sun?"
There have been a number of responses to this article from various members of the Microsoft community such as Clemens Vasters, Robert McLaws, and Wally. Generally speaking, I agree with their responses, and they have more eloquently made the argument than I could. So, I will simply throw in my two cents and let it go. As pointed out in their blog posts, there are beaucoup examples of a vibrant, passionate Microsoft community. Don't believe me? Drop by a Code Camp or User Group Meeting sometime. Or, attend a conference such as Mix, TechEd, or PDC.
I have witnessed the excitement of these events and talked with plenty of developers to convince me there is a passionate Microsoft community that is experiencing continued growth. From my point of view, the MS community has a plentiful supply of developers championing the technology.
Thoughts?
I am on vacation this week. As such, I have been extremely lax on posts. Actually, I haven't made any posts at all. Originally, I had intended to write about one or two things this week. However, I lost most of my drive to do so once arriving at the beach.
So, where am I? Until Saturday, I am down at Panama City Beach. I have been here since last Saturday. We couldn't have asked for better weather. It has been great...just a little warm for my taste. Otherwise, it has been a great escape from the office and other stuff.
At any rate, I thought I would take the easy way out and defer you to another blogger in my absence. Robert Cain, aka Arcane Code, has been running a blog for some time now. He has turned into quite the blogging machine. Typically, he posts once every weekday. Robert writes about a wide variety of subjects, but most of it centers around Microsoft .NET. However, I have even seen a few posts about Ubuntu.
He is a great addition to the Southeast blogging community for Microsoft technologies. I would definitely recommend subscribing to his blog. The chances are that you will see something that interests you. Here is a link to his FeedBurner feed: http://feeds.feedburner.com/ArcaneCode.
The May meeting for the Internet Professionals Society of Alabama will be on Thursday, May 17th. The meeting will be held from 12PM to 1PM at the McWane Science Center in downtown. The presentation will be located in the Special Event Center on the 3rd floor. There will be designated networking time from 11:30AM to 12PM prior to the beginning of the presentation.
Lee Farabaugh will be presenting on Information Architecture. She is the Directory of Usability at PointClear Solutions. The presentation will cover the history of Information Architecture, why its important, and how it can benefit your daily workflow. There will be some real world case studies to demonstrate example methods such as content inventory, card sorting, mental models, and more.
Please RSVP to attend to the event.
Normally, I would say "I hope to see you there." However, I will be out of town on vacation. So, I will see you next time.
Recently, I have been spending some time blogging about serialization. This is partially in an effort to go back over some of the basics prior to starting on WCF and P2P in a week or so. Today, I am continuing the serialization subject by taking a closer look at generics in regards to serialization.
This is actually a popular subject for a lot of newcomers to WCF. Many developers who are fond of generics will create a service that exposes some generic method. When they finally get ready to fire up the service and give it a trial run, they are quickly disappointed to discover that it doesn't work as expected.
So, what's the deal?
WCF does not support the use of generic methods for service operation. In other words, only concrete types can be used for service operations. Open generic types cannot be used. Now, it is important to clarify this is not a limitation of WCF. Rather, it is a limitation of WSDL, which is used to expose service metadata to consumers. There is no construct within WSDL to define a generic type. Generally speaking, I agree with this behavior since it decreases the coupling between a client and service.
Although generic methods are not supported, it is possible to expose generic objects for the purpose of exchanging data. However, there are some limitations. Let's take a closer look:
Bounded Generics
In his book Programming WCF Services , Juval Lowy points out that it is possible to use "bounded generics." This is sometimes referred to as closed generics. Basically, it refers to defining a generic class for your data contract, but it is restricted to a specific type in the service operation. This may sound somewhat vague. So, here is an example to provide a better illustration:
[DataContract]
public class MyGenericObject<T>
{
private T _id;
private string _description;
public MyGenericObject()
{
}
[DataMember]
public T ID
{
get { return _id; }
set { _id = value; }
}
[DataMember]
public string Description
{
get { return _description; }
set { _description = value; }
}
}
[ServiceContract(Namespace = "http://jeffbarnes.net/2007/05/boundedgenerics/")]
public interface IBoundedGenerics
{
[OperationContract]
MyGenericObject<int> GetGenericObject(int id);
}
As you can see, a generic object (MyGenericObject<T>) is exposed to the client. However, the service operation restricts the usage to being of type integer. This is what Juval Lowy means by "bounded generics." However, it should be noted the client will not see the object as a generic. When the metadata is generated to describe the service operation, the data contract and service operation will appear as a normal non-generic class.
[DataContract]
public class MyGenericObjectOfint
{
private int _id;
private string _description;
public MyGenericObjectOfint()
{
}
[DataMember]
public int ID
{
get { return _id; }
set { _id = value; }
}
[DataMember]
public string Description
{
get { return _description; }
set { _description = value; }
}
}
The resulting name is due to an applied naming pattern that consists of:
Generic Class Name + "Of" + Type Parameter Name + Hash
The hash is added under certain conditions to reduce the risk of a name collision. However, you should be aware the hash can create a really ugly class name. It could be something like: MyGenericObjectOfSomeTypegDh87uV. Obviously, this isn't an ideal name for the client to use. Fortunately, you can override the use of the hash by specifying the Name property of the DataContract. It supports parameters that correspond to the generic type parameters. For example:
[DataContract(Name = "MyGenericObjectUsing{0}"]
public class MyGenericObject<T>
Using this approach, it is still possible to leverage generics from within the service implementation, but there is nothing special going on from the client's perspective.
You can download the sample code from here.
Back in mid-April, I posted some information about a WCF presentation that I would be giving at the Huntsville New Technology Users Group on Monday, May 21. Unfortunately, a business engagement has surfaced that requires me to attend as a WCF resource on the same day. Due to the involved schedule, it would be difficult for me to reach the user group meeting on time. Since I don't think it would be fair to the group for me to say that I will "hopefully" be there, I have decided to cancel my scheduled presentation.
On a personal note, I absolutely hate doing this sort of thing. As a speaker, it reflects poorly on me when I cancel a presentation...especially when it is just under two weeks until the date. Hopefully, the user group can understand my reasons and still feel up to inviting me back sometime in the future.
When working with data contracts, you may come across a situation where there is a preference to the order in which members are serialized. It could be due to some dependency on the value that requires them to be serialized in a particular order. Or, maybe you are just very picky about the appearance of the the resulting xml. Regardless, there will likely be some occasions where the default serialization order doesn't work for you.
What is the default serialization order? I'm glad you asked!
- If the data contract type is a derived class, the members of the base type will always be serialized first.
- If no order is specified, the members will be serialized in alphabetical order based on an ordinal comparison.
- Any members with a specified order will be serialized from least to greatest. If two members share the same order, the serialization order will be determined by Rule #2.
Let's look at an example to put this into context.
Here is a simple service interface that provides a method for retrieving book information.
[ServiceContract(Namespace = "http://jeffbarnes.net/2007/05/bookservice/")]
public interface IBookService
{
[OperationContract]
Book GetBook();
}
Now, let's examine the data contract for the Book class hierarchy:
[DataContract(Namespace = "http://jeffbarnes.net/2007/05/bookservice/book/")]
[KnownType(typeof(ModernBook)]
public class Book
{
[DataMember]
public string Name;
[DataMember]
public string Author;
[DataMember]
public string Publisher;
[DataMember]
public DateTime ReleaseDate;
[DataMember]
public string Isbn;
[DataMember]
public int NumberOfPages;
public Book()
{
}
}
[DataContract(Namespace = "http://jeffbarnes.net/2007/05/libraryservice/modernbook/")]
public class ModernBook : Book
{
[DataMember]
public string Isbn13;
public ModernBook() : base()
{
}
}
Notice there is no order specified anywhere in the data contract. After setting up the necessary service diagnostics, it is possible to log the actual SOAP messages that are exchanged between the client and server. Here is the SOAP message returned for the data contract based on the service implementation:
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<a:Action s:mustUnderstand="1">http://jeffbarnes.net/2007/05/bookservice/IBookService/GetBookResponse</a:Action>
</s:Header>
<s:Body>
<GetBookResponse xmlns="http://jeffbarnes.net/2007/05/bookservice/">
<GetBookResult xmlns:d4p1="http://jeffbarnes.net/2007/05/bookservice/book/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d4p3="http://jeffbarnes.net/2007/05/libraryservice/modernbook/" i:type="d4p3:ModernBook">
<d4p1:Author>Juval Lowy</d4p1:Author>
<d4p1:Isbn>0596526997</d4p1:Isbn>
<d4p1:Name>Programming WCF Services</d4p1:Name>
<d4p1:NumberOfPages>634</d4p1:NumberOfPages>
<d4p1:Publisher>O'Reilly Media, Inc.</d4p1:Publisher>
<d4p1:ReleaseDate>2007-02-20T00:00:00</d4p1:ReleaseDate>
<d4p3:Isbn13>978-0596526993</d4p3:Isbn13>
</GetBookResult>
</GetBookResponse>
</s:Body>
</s:Envelope>
As you can see, the members of the Book and ModernBook types serialized as outlined in the previously mentioned rules. Now, let's specify an order to the data members and see how it looks. Here are the revised data contracts:
[DataContract(Namespace = "http://jeffbarnes.net/2007/05/bookservice/book/")]
[KnownType(typeof(ModernBook)]
public class Book
{
[DataMember(Order = 0)]
public string Name;
[DataMember(Order = 1)]
public string Author;
[DataMember(Order = 4)]
public string Publisher;
[DataMember(Order = 5)]
public DateTime ReleaseDate;
[DataMember(Order = 2)]
public string Isbn;
[DataMember(Order = 6)]
public int NumberOfPages;
public Book()
{
}
}
[DataContract(Namespace = "http://jeffbarnes.net/2007/05/libraryservice/modernbook/")]
public class ModernBook : Book
{
[DataMember(Order = 3)]
public string Isbn13;
public ModernBook() : base()
{
}
}
Notice that the Order property was simply added to specify the order in which serialization should occur. Once again, here is the SOAP message that results from the data contract:
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<a:Action s:mustUnderstand="1">http://jeffbarnes.net/2007/05/bookservice/IBookService/GetBookResponse</a:Action>
</s:Header>
<s:Body>
<GetBookResponse xmlns="http://jeffbarnes.net/2007/05/bookservice/">
<GetBookResult xmlns:d4p1="http://jeffbarnes.net/2007/05/bookservice/book/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d4p3="http://jeffbarnes.net/2007/05/libraryservice/modernbook/" i:type="d4p3:ModernBook">
<d4p1:Name>Programming WCF Services</d4p1:Name>
<d4p1:Author>Juval Lowy</d4p1:Author>
<d4p1:Isbn>0596526997</d4p1:Isbn>
<d4p1:Publisher>O'Reilly Media, Inc.</d4p1:Publisher>
<d4p1:ReleaseDate>2007-02-20T00:00:00</d4p1:ReleaseDate>
<d4p1:NumberOfPages>634</d4p1:NumberOfPages>
<d4p3:Isbn13>978-0596526993</d4p3:Isbn13>
</GetBookResult>
</GetBookResponse>
</s:Body>
</s:Envelope>
As you can see, this time the serialization occurred in the order specified within the data contracts. If you look closely, you will notice one potentially unexpected issue. In the ModernBook class, an Order of 3 was specified for Isbn13. However, Isbn13 is still the last member that was serialized since it was at the bottom. This is due to ModernBook being a derived class of Book. Since it is lower in the inheritance hierarchy, it will still be serialized after the Book members.
This is a limitation of the DataContract. It doesn't support the ability to serialize derived class members prior to base class members. In most cases, this is probably acceptable. However, you may run into a situation where you really want derived class members to serialize prior to base class members. If so, you will have to use a more customized serialization method, which will be covered later in the week.
The example code can be downloaded here.
A couple of weeks ago, a customer was having trouble using a WCF service from a client-side ASP.NET AJAX script. Unfortunately for the customer, the current release of ASP.NET AJAX doesn't currently support direct communication with a WCF service. Direct support for WCF was removed for the official release of ASP.NET AJAX, but it is scheduled to be included within the Orcas release coming late this year. Fortunately, there is a temporary solution that allows communication between ASP.NET AJAX and WCF.
Rather than directly accessing WCF from a client-side script, an ASMX web service can be used to wrap the WCF service. The client-side script will communicate with the ASMX web service, and the ASMX web service will forward the request directly to the WCF service. This does result in some additional overhead. However, it provides a clean "forward looking" solution that easily enables adoption of direct WCF communication when Orcas is released. Once the functionality is released, you can simply drop the ASMX wrapper and the client script can directly talk to WCF with minimal effort.
This has likely been covered in other places, but it still seemed like a useful tidbit of information to pass along.
More Posts
Next page »
Disclaimer:The opinions and views expressed within this blog are solely my own and do not represent those of my employer or anyone else.