Serialization error when property is declared as base class, but populated by derived class


 
I’ve receive  quite generic error Message :
 Type ‘MyclassType’ with data contract name ‘MyclassType:http://schemas.datacontract.org/myNamespace’ is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types – for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
Type : System.Runtime.Serialization.SerializationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089


After investigation I found that the class that I tried to serialize, had a property declared of the base class, but at runtime derived class was assigned, and serialization was unable to resolve it.
The fix was simple- to add KnownType property to container class.

    [KnownType(typeof(MyclassType))]
public class Mycontainer 
{
 MyBaseclass PropertyOfmyClass { get; set;}
…….
}

public class  MyclassType : MyBaseclass
{ ….}

Unfortunately, the serialization time error message didn’t specify the name of container class , not the name of property. it makes harder to fix the error.

Response for REST method was truncated because default MaxItemsInObjectGraph was not big enough.

We have a   REST service with attributes [WebGet(UriTemplate =“…”, BodyStyle =WebMessageBodyStyle.Bare, ResponseFormat =WebMessageFormat.Xml)]

Normally it worked fine. But for particular data it has a huge response that was truncated. 

The size returned in a few attempts in IE browser was 2196456, in Chrome slightly different 2195397.


After a search in google I found http://forums.asp.net/post/4948029.aspx, that has a number of suggestions.

 

For WCF service that will transfer large amount of data in operations, here are the configuration settings you need to check:

1) the maxReceivedMessageSize attribute of the certain <binding> element(in your case, that’s the webHttpbinding)

#<webHttpBinding> 
http://msdn.microsoft.com/en-us/library/bb412176.aspx

2) The <readerQuotas> settings (under the <binding> elements) which has control over the maxarrayLength, maxStringLength ,etc…

#<readerQuotas> 
http://msdn.microsoft.com/en-us/library/ms731325.aspx

3) The DataContractSerializer behavior which has a MaxItemsInObjectGraph property. You can configure it via ServiceBehavior of your WCF service

#DataContractSerializer.MaxItemsInObjectGraph Property 
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.maxitemsinobjectgraph.aspx

4) And if your WCF service is hosted in ASP.NET/IIS web application, you also need to enlarge the “maxRequestLength” attribute of the <httpRuntime> element (under <system.web> section).

#httpRuntime Element (ASP.NET Settings Schema) 
http://msdn.microsoft.com/en-us/library/e1f13641.aspx

 After a few attempts my collegue found that our problem was caused by

#DataContractSerializer.MaxItemsInObjectGraph Property 
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.maxitemsinobjectgraph.aspx

 

<behavior name=“MyOperationBehavior>
          < dataContractSerializer maxItemsInObjectGraph =2196456 />
</behavior>

WCF Transactions are not supported by Azure.

We have a service operation, for which it is very important to ensure that a client receives the status, that was determined at the end of operation.
If client does receive the response, the server status should be “completed”. Otherwise (in case of communication error), server status should be rollback and stay as “pending”. The possible technical solutions were discussed and WCF Transactions support with  2PC(two phase commit) was selected.  We implemented service operation with transaction commit/rollback support and asked our clients to use it.
Our main client is running on Azure. It was a big disappointment, when Readify consultant Himanshu Desai  adviced that WCF Transactions are not supported by Azure.
I did a quick check on Internet and didn’t find that is well known issue.
Below are a few quotes to describe the limitation:

2PC in the cloud is hard for  all sorts of reasons. 2PC as implemented by DTC effectively depends on the coordinator and its log and connectivity to the coordinator to be very highly available. It also depends on all parties cooperating on a positive outcome in an expedient fashion. To that end, you need to run DTC in a failover cluster, because it’s the Achilles heel of the whole system and any transaction depends on DTC clearing it.

The bottom line is that Service Bus, specifically with its de-duplication features for sending and with its reliable delivery support using Peek-Lock (which we didn’t discuss in the thread, but see here and also here) is a great tool to compensate for the lack of coordinator support in the cloud

The Azure storage folks implement their clusters in a very particular way to provide highly-scalable, highly-available, and strongly consistent storage – and they are using a quorum based protocol (Paxos) rather than classic atomic TX protocol to reach consensus. 

In the current release, only one top level messaging entity, such as a queue or topic can participate in a transaction, and the transaction cannot include any other transaction resource managers, making transactions spanning a messaging entity and a database not possible.

Has Windows Azure any kind of distributed transaction mechanism in order to include any remote object creation in an atomic transaction including other domain-specific operations?  
The alternative solution suggested by Himanshu Desai is to have an operation to start a process on the server and then poll in a loop on a client until final status is received from the server. 

 

maxItemsInObjectGraph limit required to be changed for server and client

We have a wcf service, that expects to return a huge XML data. It worked ok in testing, but in production it failed with error  "Maximum number of items that can be serialized or deserialized in an object graph is '65536'. Change the object graph or increase the MaxItemsInObjectGraph quota."

The MSDN article about   dataContractSerializer xml configuration  element  correctly  describes maxItemsInObjectGraph attribute default as 65536, but documentation for of the 

DataContractSerializer.MaxItemsInObjectGraph property and DataContractJsonSerializer.MaxItemsInObjectGraph Property 

are talking about Int32.MaxValue, which causes confusion, in particular because Google shows properties articles before configuration articles.


When we changed the value in WCF service configuration, it didn’t help, because the similar change must be ALSO done on client.

There are similar posts:
You need to set the MaxItemsInObjectGraph on the dataContractSerializer using a behavior on both the client and service. See  for an example.http://devlicio.us/blogs/derik_whittaker/archive/2010/05/04/setting-maxitemsinobjectgraph-for-wcf-there-has-to-be-a-better-way.aspx
 I had forgot to place this setting in my client app.config file.
It seems that DataContractJsonSerializer.MaxItemsInObjectGraph has actual default 65536, because there is no configuration for JSON serializer, but  it complains about the limit.

I believe that MS should clarify the properties documentation re default limit and make more specific error messages to distinguish server side and client side errors.
Note, that as a workaround it’s possible to use commonBehaviors section which can be defined only in machine.config:
<commonBehaviors>
<behaviors>
<endpointBehaviors>
<dataContractSerializer maxItemsInObjectGraph="..." />
</endpointBehaviors>
</behaviors>
</commonBehaviors>

v

Using interfaces in DataContracts for WCF service versioning.

We are implementing WCF Service versioning after having problems  with enums in response  (  Do not expose enum in WCF response )
I found that we need rigorously follow the recommendations “Versioning When Schema Validation Is Not Required” from msdn article:
Best Practices: Data Contract Versioning

Initially I’ve ignored the recommendation “Do not attempt to version data contracts by type inheritance” and failed to generate backward compatible XML.

Reading the documentation I’ve noticed in Service Versioning article
an example
public interface IPurchaseOrderV2
{
   DateTime OrderDate { get; set; }
}
which includes only one new field. It is used in

[DataContract(
Name = “PurchaseOrder “,
Namespace = “http://examples.microsoft.com/WCF/2006/02/PurchaseOrder”)]
public class PurchaseOrderV2 : IPurchaseOrderV1, IPurchaseOrderV2
{
   [DataMember(…)]
   public DateTime OrderId {…}
   [DataMember(…)]
   public string CustomerId {…}
   [DataMember(…)]
   public DateTime OrderDate { … }
}

I believe that it would it be more appropriate to have IPurchaseOrderV2 derived from IPurchaseOrderV1.

public interface IPurchaseOrderV2: PurchaseOrderV1
{
   DateTime OrderDate { get; set; }
}

I asked myself,  should I repeat all properties from original in a new interface and would it give any benefits to versioning.

public   interface IPurchaseOrderV2  
{
   public DateTime OrderId { get; set; }
   public string CustomerId { get; set; }
   public DateTime OrderDate { get; set; }
}
but I was on a wrong track.
Interface is not allowed to be marked as DataContract.The reason is explained in  the answer of
http://stackoverflow.com/questions/4720730/wcf-and-interfaces-on-data-contracts

XML schema doesn’t know anything about interfaces – it’s all about concrete, actual types.

Using interfaces for service contracts are recommended, however  interfaces in dataContracts are not exposed externally.
i’ve checked the article again and found that the appendix  in MSDN  actually is quite clear:
write INTERNAL implementation code in terms of the interfaces rather than the data contract classes that implement the interfaces.
I just confused myself by quick browsing instead of proper reading.

ResolveUrl() from WCF service

I wanted to ResolveUrl() from WCF service and found

http://www.west-wind.com/weblog/posts/2007/Sep/18/ResolveUrl-without-Page .
However the function assumes that the call is synchronous, in asynchronous call (e.g called from TPL task) HttpContext.Current==null.
I had to split my asynchronous method into two-a long asynchronous one, invoked as task and generating relative URL and a post-task, that is calling wwWebUtils.ResolveServerUrl(relativeUrL)

The http://www.codeproject.com/Articles/205425/ASP-NET-ResolveUrl-Without-Page  article suggests to use
System.Web.VirtualPathUtility.ToAbsolute(“~/default.aspx”);
but i expect, it wouldn’t work from asynchronous thread as well.

Do not expose enum in WCF response

We had a backward compatibility problem in WCF client, when in Service application a new value was added to one of enums. We discussed different ways to avoid this backward compatibility issues, and I found recommendation do not expose enum in wcf response in http://stackoverflow.com/a/788281/52277.

It is still required to create new versions of our service interfaces to replace each enum fields with string field, that expects only documented values, and describe, what should be default behavior, if field has an unexpected value.

 

As a workaround for backward- compatibility of enums, they can be declared as [DataContract] and only old values set as [DataMember] , but left new values without the attribute until the new MAJOR release.Members that are not marked are not serialized.  See Enumeration Types in Data Contracts.