Symptoms
You may run into errors while accessing fault details in the client proxy generated by using 'Add Service Reference' in Visual Studio 2010 if the FaultContract detail is an unqualified array. You may also notice that you do not run into this issue in Visual Studio 2008.
One possible error message could be “The type or namespace name does not exist in the namespace (are you missing an assembly reference?)”.
Another symptom may be that the InnerXml property of the return value from MessageFault.GetDetail<XmlElement>() is “” (string.Empty), even when traces show that there is Xml present in the fault message detail.
Cause
There is a design change in Visual Studio 2010 to use XMLSerializer for faults while generating the proxy. This exposes a known bug in WCF where it expects a qualified array by default.
To provide more detail,
In VS 2010, 'Add Service Reference' sets 'UseSerializerForFaults' to true where as it was set to false in VS2008. 'UseSerializerForFaults' switch uses XMLSerializer. VS2008 does not turn this switch on and hence, dataContractSerializer is used for faults.
Resolution
We suggest the following Workaround to address the issue.
Use svcutil to generate the proxy. Svcutil, by default, does not use XmlSerializer for faults. The following command provides equivalent proxy to what Visual Studio generates(with default settings) with the difference that svcutil command below does not use XmlSerializer. [Please refer to More Information section for further detail]
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\SvcUtil.exe> svcutil http://localhost/MyServices/Service.svc?WSDL /n:<targetNamespace>,<clientNamespace> /edb /s /r:”<yourAssembly1.dll>” /r:”<yourAssembly2.dll>”
where
Switches |
Description |
/n:<targetNamespace>,<clientNamespace> |
<targetNamespace> - WSDL or XML schema targetNamespace. |
/edb |
Enables Data Binding - Implements the INotifyPropertyChanged interface on all Data Contract types to enable data binding. |
/s |
Generates classes marked with the Serializable Attribute. |
/r:<assembly name> |
Reference the assemblies that the client shares with the service if you want to ensure that the types defined in these assemblies are not regenerated. |
More Information
The following content from reference.svcmap shows the settings that Visual Studio 2010 uses to generate the proxy. [Note: You can access reference.svcmap in the client project in the Solution Explorer under your service reference, by selecting ‘Show all files” icon. It is hidden by default.]
<ClientOptions>
<GenerateAsynchronousMethods>false</GenerateAsynchronousMethods>
<EnableDataBinding>true</EnableDataBinding>
<ExcludedTypes />
<ImportXmlTypes>false</ImportXmlTypes>
<GenerateInternalTypes>false</GenerateInternalTypes>
<GenerateMessageContracts>false</GenerateMessageContracts>
<NamespaceMappings />
<CollectionMappings />
<GenerateSerializableTypes>true</GenerateSerializableTypes>
<Serializer>Auto</Serializer>
<UseSerializerForFaults>true</UseSerializerForFaults>
<ReferenceAllAssemblies>true</ReferenceAllAssemblies>
<ReferencedAssemblies />
<ReferencedDataContractTypes />
<ServiceContractMappings />
</ClientOptions>
Notice that in reference.svcmap, 'UseSerializerForFaults' is true - and this is exactly what we are trying to avoid in the workaround. The default is to use DataContractSerializer and that is what gets used by using the command provided.
Also note that svcutil has a default of false for 'EnableDataBinding', 'GenerateSerializableTypes', 'UseSerializerForFaults' and 'ReferenceAllAssemblies'. To Enable DataBinding and Generate Serializable types, the command used in the workaround above uses /edb and /s. In order to reuse the types in the referenced assemblies, you need to provide each referenced assembly with a /r: switch
If you would like to get the equivalent of checking the 'message contract' checkbox in Visual Studio ASR (Add Service Reference), include /messageContract in your svcutil command.
If you would like to target a specific .NET version, say 3.5 - you can do so using /targetClientVersion switch
Below is an example of using svcutil command when enabling message contracts and targetting 3.5 Framework
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\SvcUtil.exe> svcutil http://localhost/MyServices/Service.svc?WSDL /n:<targetNamespace>,<clientNamespace> /edb /mc /tcv:Version35
Reference
http://msdn.microsoft.com/en-us/library/aa347733.aspx