|
>
 Sunday, November 12, 2006
 |
|
 |
|
|
|
|
|
A big thanks to all the participated in this monstrous tutorial at Dev Connections. Whew, I can fully admit it was a lot of work to put all the information together in one place, but I hope that you got a lot out of it. For those that didn't attend, the goal of the tutorial was to provide an overview of the current state of the various technologies and tools for Microsoft developers, with an emphasis on the reasons for moving forward with each technology stack, and hopefully some enlightenment on when you might choose each technology. I'll be keeping this one day session current for future conferences, and for on-site sessions with clients. If you are interested in such a thing, contact me at IDesign: www.idesign.net.
Here are the resources I promised from the tutorial.
Development Tools
In this section I reviewed the stack of development tools and explained how to choose between them.
Language Enhancements
In this section I talked about moving from .NET 1.1 to 2.0, and discussed the key features of 2.0 that folks should be leveraging. Then, I focused on the language enhancements forthcoming with C# 3.0 and VB 9.0.
Demos:
Data Access
In this section I focused on data access technologies, designing the data access tier, and key features of ADO.NET 2.0, vNext and LINQ to give you some idea how to prepare for the next set of innovations.
Demos:
- When you install ADO.NET vNext and LINQ there are numerous overview documents, tutorials, and samples that will really help you get up to speed here. These are the demos that I showed in the tutorial.
Windows Development
In this section I reviewed Windows Forms 2.0 innovations, primarily ClickOnce, and then talked about how to prepare for WPF and who should use it today.
Demos:
Web Development
In this section I showed an ASP.NET sample application that illustrates key features of ASP.NET 2.0 and practical application of those features. Then we looked at AJAX and discussed trends on the Web compared to Windows development.
Popular AJAX Frameworks:
Demos:
Distributed System Programming
In this section I reviewed the typical use for earlier distributed computing technologies like remoting, enterprise services and ASMX web services with WSE, and compared them with WCF.
BPM and Workflow
In this section I discussed BPM, BizTalk and workflow.
|
|
|
 |
|
 |
 Thursday, October 26, 2006
 |
|
 |
|
|
|
|
|
As some of you may now, localization architcture is one of the subject areas that I have always enjoyed. THough I am in the midst of my WCF book, a few months ago I did wrap up a whitepaper for MSDN on the subject of custom resource providers and custom localization expressions. I also learned a lot in the process, with some great feedback from the product team, specifically Simon Calvert and Eilon Lipton, who pointed me in the right direction for how things work under the covers. In this article you'll learn about custom resource managers, storing resources in the database, accessing resources from external assemblies instead of using the App_GlobalResources directory, and creating custom localization expressions to tie it all together. I hope you enjoy this!
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/ExASPNET20RPM.asp
I'll be writing two follow up whitepapers in this series, a little later this year when I wrap up my book. The subject will be hooking the IDE to help you with your localization dev process and creating complex culture hierarchies that are customizable for personalization. Stay tuned!
|
|
|
 |
|
 |
 Thursday, October 12, 2006
 |
|
 |
|
|
|
|
|
For those of you who are attending our .NET 3.0 roadshow (http://www.net3roadshow.com/) here are the updated code samples for my WCF Security and CardSpace talks. As I mentioned in each session, the code has changed since June/July CTP. These samples have been updated for RC1/Sept CTP.
http://www.dasblonde.net/downloads/wcf/CMPSecurityDemos.zip
Also, for those of you who attended the LA show, I forgot to mention that I know of a great job opportunity in Irvine, CA. The company is building a VERY interesting system based on all .NET 3.0 technologies and AJAX. They are hiring now, so if you are looking for this type of opportunity, email me and I'll connect you to explore further. mlb@idesign.net
-Michele
|
|
|
 |
|
 |
 Monday, September 25, 2006
 |
|
 |
|
|
|
|
|
When you own both sides (client and service) it can be more effective for developers to share assemblies for shared types, instead of relying on proxy generation to duplicate types from WSDL. Furthermore, if you want to work with strongly typed collections at the client, and I don't mean BindingList<T>, you may want to specify which collection type.
Here's the SvcUtil command to make this a reality:
svcutil /d:d:\LearningWCF /noconfig /o:serviceproxy.cs /r:ContentTypes.dll /ct:System.Collections.Generic.List`1 http://localhost:8000
One of the reasons that I blogged this seamlingly obvious instruction is because I got caught using a single quote (List'1) instead of a backquote character (List`1) and things were not working quite right. I didn't see it (better glasses?) but Eugene on the WCF team helped me find my way. It's the little things that take up your time!
Cheers!
|
|
|
 |
|
 |
 Thursday, September 21, 2006
 |
|
 |
|
|
|
|
|
I was intrigued by this forum discussion about attaching context to the lifetime of a service operation.
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=733385&SiteID=1
Basically, the question is how to create the equivalent of the HttpContext we have with ASP.NET requests. The OperationContext is the closest we have to a request lifecycle, and it turns out you can add to the context by implementing IExtension<OperationContext>.
Attached is a sample: CustomContext.zip (91.4 KB)
Here's how it works:
- I use a custom attribute at the service, that implements IServiceBehavior.
[ApplicationRequestContext] public class HelloIndigoService : IHelloIndigoService
- In IServiceBehavior.ApplyDispatchBehavior() I add a custom message inspector to the MessageInspectors collection for each endpoint. This makes it possible to intercept at the point messages are received, and just before reply messages are sent. In my example, the ApplicationRequestContextAttribue also implements IMessageInspector.
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers) { foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints) { endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this); } } }
- In IMessageInspector.AfterReceiveRequest() I add an instance of my ApplicationRequestContext to the OperationContext, like this:
OperationContext.Current.Extensions.Add(new ApplicationRequestContext());
- In IMessageInspector.BeforeSendReply() I remove the instance of ApplicationRequestContext from the OperationContext. In my opinion, this step should not be necessary, but without it you will not have a chance to clean up what you created in the ApplicationRequestContext to speed up garbage collection.
OperationContext.Current.Extensions.Remove(ApplicationRequestContext.Current);
- The IExtension<OperationContext> implementation has an Attach() and Detach() implementation. In Attach() you intitialize your context. In Detach(), cleanup.
- Anywhere else in the application when you want access to the context, you get it from the OperationContext.Current. I provide a static member in the custom context to get this information:
public static ApplicationRequestContext Current { get {return OperationContext.Current.Extensions.Find<ApplicationRequestContext>();} }
Many thanks to Scott Mason on the WCF team for helping me find the right hooks for this purpose...
|
|
|
 |
|
 |
 Tuesday, September 19, 2006
 Saturday, September 16, 2006
 |
|
 |
|
|
|
|
|
To follow my post on Service Contract Versioning, here's a snip from my book on Data Contract Versioning.
-----
This lab illustrates several versioning scenarios for data contracts. Table 2-5 summarizes possible changes to a data contract and the affect it has on existing clients, if any.
|
Data Contract Changes |
Impact on Existing Clients |
|
Add new non-required members |
Client unaffected. Missing values are initialized to defaults. |
|
Add new required members |
An exception is thrown for missing values. |
|
Remove non-required members |
Data lost at the service. Unable to return the full data set back to the client, for example. No exceptions. |
|
Remove required members |
An exception is thrown when client receives responses from the service with missing values. |
|
Modify existing member data types |
If types are compatible no exception but may receive unexpected results. |
Making changes to data contracts once they have been published is a delicate matter. Even if no exception is thrown for the change, the data may lack integrity once deserialized on either end. To avoid this, a few general guidelines should be followed if you are not creating a new data contract version:
Require data members the business depends on.
Do not remove or change data types for members, ever.
If adding new members, make sure they are not required so that version 1 clients don’t break. Remember that missing fields will be initialized to default values — so you must be sure these defaults are acceptable, or perform some low level message inspection to provide meaningful defaults prior to deserialization.
Support IExtensibleDataObject so that extra data sent by clients, or returned by services, is preserved for round trips.
As the lab illustrates, implementing this interface allows you to preserve unknown members sent in the data contract message element (for example if a version 2 client sends a message to a version 1 service). Predicting future versioning issues is difficult, so providing this property bag for unknown members can ease versioning pain.
If at a later time you decide this is not a desirable feature, you can suppress support for unknown members with the dataContractSerializer behavior:
<behavior name="serviceBehavior">
<dataContractSerializer ignoreExtensionDataObject ="true"/>
</behavior>
If you are wondering about the client side — it so happens that SvcUtil generates data contracts that implement IExtensibleDataObject. This ensures that extra data sent to clients by the service will not be lost in a round trip.
On either side the result is that the DataContractSerializer populates the ExtensionDataObject dictionary on deserialization, and uses the same dictionary to serialize additional elements in outgoing messages.
To properly version a data contract you should create a new type and supply it with a new data contract name and/or namespace using the DataContractAttribute. Since it is a new type, you are free to remove, add, or change any member — but remember that if the semantics of the type are significantly different then it should probably be a new type altogether, without relation to the original.
When you change a data contract that is included in a service contract operation, you are also affecting the service contract that exposes the type. In fact, the minute you decide to version a data contract you must also version any service contract that uses it, or supply new contracts for the new type.
In summary, existing clients must always be able to access an endpoint that exposes the original contract. The only way this is possible is if the original contract does not change!
Versioning Flow Diagrams
Figure 2-7 and Figure 2-8 illustrate the decision flow for data contract versioning based on non-strict and strict approaches, respectively.
With non-strict versioning you can add optional members and ignore (yet preserve) superfluous members that may result from future versions of the contract. Ignoring optional members requires you to be aware of the default initialization of members that are missing, if you want to differentiate from version 1 and version 2 clients. Allowing superfluous members to be ignored solves the problem of newer version clients pushing data to an older version of the data contract, but this carries risks if clients send an inordinate amount of extra data. You should still consider IExtensibleDataObject for your own versioning needs, but perhaps monitor the message size for possible denial-of-service attacks.
With strict data contract versioning all changes lead to a new data contract. That means that any service contract that exposes this new data contract must also be versioned per the rules of strict service contract versioning.
Click image for full view...

|
|
|
 |
|
 |
 |
|
 |
|
|
|
|
|
Oh my, is it really a new post from little 'ole me? Yes, I have been very busy with various projects, including my Learning WCF book which I'm trying to wrap in the next month here...
I am getting a lot of questions about contracts and versioning, and since I have some sections in my book to address this, I thought I'd post them here. Starting with service contracts.
From the book:
-----
This lab illustrates that the service model is by default version tolerant. Table 2-2 summarizes some possible changes to a service contract and the affect it has on existing clients, if any.
|
Service Contract Changes |
Impact on Existing Clients |
|
Adding new parameters to an operation signature |
Client unaffected. New parameters initialized to default values at the service. |
|
Removing parameters from an operation signature |
Client unaffected. Superfluous parameters pass by clients are ignored, data lost at the service. |
|
Modifying parameter types |
An exception will occur if the incoming type from the client cannot be converted to the parameter data type. |
|
Modifying return value types |
An exception will occur if the return value from the service cannot be converted to the expected data type in the client version of the operation signature. |
|
Adding new operations |
Client unaffected. Will not invoke operations it knows nothing about. |
|
Removing operations |
An exception will occur. Messages sent by the client to the service are considered to be using an unknown action header. |
· The bulk of these changes have no direct affect on clients, although the results may be undesirable. The forgiving nature of the service model can be a blessing or a curse depending on how you look at it. Here are some downsides:
You can unwittingly lose information passed by the client
Missing data from the client may not be detected
Type conversions may work, yet the data is semantically invalid
· You can remove the risks of these unexpected results by using data contracts as message parameters and return types. I’ll discuss data contracts in the next section.
· Of course you are entitled to come up with your own strategy for version tolerance, but I recommend that if the implementation semantics of the service contract have changed or if new clients are to be given additional features via extended parameters and/or new operations — you should version the service contract, rather than accepting version tolerance.
To properly version a service contract you should provide a new contract and modify the namespace specified in the ServiceContractAttribute. To version the namespace, you can supply a new value for the year and month, if you follow the naming conventions I’ve recommended. A new contract name should also be specified if the contracts aren’t inherited. In the next two sections I’ll compare two versioning approaches.
· One likely scenario is that you will add new operations without changing the existing service contract. But, you may want to support these new operations at the same endpoint. You can achieve this by creating a new contract that inherits the old contract, adding new operations to the new one. Consider the contract shown in Example 2-8 as the first published version of the service contract.
[ServiceContract(Name="ServiceAContract",
Namespace = "http://www.thatindigogirl.com/samples/2006/06")]
public interface IServiceA
{
[OperationContract]
string Operation1();
[OperationContract]
string Operation2();
}
· The endpoint configuration for the service implementing the contract might look like this:
<endpoint address="ServiceA" contract="BusinessServiceContracts.IServiceA" binding="basicHttpBinding" />
· When new operations are added to the service to extend its features, you may want to expose the same endpoint to old and new clients while still somehow tracking the contract version related to new features. If you extend the original service contract you can add operations under a new namespace as shown in Example 2-9.
[ServiceContract(Name="ServiceAContract",
Namespace = "http://www.thatindigogirl.com/samples/2006/08")]
public interface IServiceA2:IServiceA
{
[OperationContract]
string Operation3();
}
· Note the service contract name is the same, but the namespace has changed. The service type can implement IServiceA2 and it will be able to expose the original operations with their original namespace, while exposing the new operation with the versioned namespace. As such, original clients can hit the same endpoint without impact, while new clients who download the metadata when version 2 is available, can access all operations.
· This scenario does not address the following:
You can’t modify existing operations with contract inheritance
You can’t differentiate old clients from new clients since they hit the same endpoint
· Another approach would be to version the entire contract and create a new endpoint for new clients. In this case, version 2 of the contract might look like that in Example 2-10.
[ServiceContract(Name="ServiceAContract2",
Namespace = "http://www.thatindigogirl.com/samples/2006/08")]
public interface IServiceA2
{
[OperationContract]
string Operation1();
[OperationContract]
string Operation2();
[OperationContract]
string Operation3();
}
· In order to provide a unique WSDL containing only one or the other contract, a unique service type must be created to implement the new contract. Both versions of the service can still share implementation behind the scenes.
· With this implementation the following applies:
You can differentiate old and new clients by service entry point
You can modify existing operations in the new interface (not recommended, you should really provide new operation names)
New clients cannot send messages to the original endpoint
Old clients cannot send messages to the new endpoint
To summarize the discussion of service contract versioning, Figure 2-4 and Figure 2-5 illustrate the decision flow for non-strict and strict-versioning policy, respectively.
Non-strict versioning allows you to add or remove parameters without versioning the service contract. This also means that the implementation code must accommodate how to handle version 1 and version 2 clients. Though possible, the idea of operation signatures changes can be very difficult to track, whereas a data contract as the service operation parameter at least allows for explicitly required and non-required parameters (to be discussed in the "Data Contracts" section of this chapter).
With strict service contract versioning, any change to an operation leads to a new service contract. A new endpoint is always provided to ensure version 2 clients can be differentiated from version 1 clients.
Click the image to see larger view...

|
|
|
 |
|
 |
 Thursday, July 27, 2006
 |
|
 |
|
|
|
|
|
There's a nice little diagnostic tool that ships with the SDK for .NET 3.0 - svctraceviewer.exe. You WILL need this tool. It is a great way to inspect messages when things are going as expected, you can see the service model trace to inspect components leading up to an exception, you can see the details leading up to a service fault, more than is shown in the inner exception at times.
Here's an example configuration for the service-side for June/July CTP:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> ... </services>
<diagnostics performanceCounters="All" wmiProviderEnabled="true"> <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="100000"/> </diagnostics> </system.serviceModel> <system.diagnostics > <sharedListeners> <add name="sharedListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="c:\logs\servicetrace.svclog" /> </sharedListeners> <sources> <source name="System.ServiceModel" switchValue="Verbose, ActivityTracing" > <listeners> <add name="sharedListener" /> </listeners> </source> <source name="System.ServiceModel.MessageLogging" switchValue="Verbose"> <listeners> <add name="sharedListener" /> </listeners> </source> </sources> </system.diagnostics> </configuration>
To view trace output launch svctraceviewer.exe and open the .svclog file. The Messages tab will take you directly to the actual messages that move between client and service, including full XML output (excluding binary data). The items in yellow are warnings, items in red are exceptions...where you can view details of the exception in the XML dump. Make sure you scroll all...the...way...down and look for the details of the exception...good stuff in there (or, bad stuff...I guess, if there is an exception).
| | |