Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

Issues accessing Fault details in WCF client proxy generated by VS2010


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.

↑ Back to the top


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.

↑ Back to the top


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

SwitchesDescription
/n:<targetNamespace>,<clientNamespace><targetNamespace> - WSDL or XML schema targetNamespace.



<clientNamespace> - namespace that will be used for generated types matching <targetNamespace>. 



Using ‘*’ for the <target namespace> maps all targetNamespaces without an explicit mapping to the <clientNamespace>. 



/n:*,ServiceReference1 would produce generated types that match the default Add Service Reference dialog (where ServiceReference1 is the default namespace).

/edbEnables Data Binding - Implements the INotifyPropertyChanged interface on all Data Contract types to enable data binding.
/sGenerates 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.

↑ Back to the top


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

↑ Back to the top


Keywords: kb

↑ Back to the top

Article Info
Article ID : 2627596
Revision : 1
Created on : 1/7/2017
Published on : 10/18/2011
Exists online : False
Views : 122