Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST with Polymorphic DataContracts - Deserialization Fails

This has been driving me nuts all day, as I've made no changes yet I swear this was working the way I had intended yesterday.

I have a WCF 4 REST service defined with the following contract:

[ServiceContract]
public interface IPhoneFeaturesManagementHost
{
    [OperationContract]
    [WebInvoke(Method = "POST", UriTemplate = "/accounts/{accountNumber}/phoneNumbers/{phoneNumber}/features/{featureType}", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare)]
    void UpdateFeatureStatus(string accountNumber, string phoneNumber, string featureType, FeatureUpdateRequest updateRequest);
}

I also have the following types defined:

[DataContract]
[KnownType(typeof(One900FeatureUpdateRequest))]
public abstract class FeatureUpdateRequest
{
    [DataMember]
    public FeatureStatus Status { get; set; }

    [DataMember]
    public DateTime EffectiveDate { get; set; }

    public string AccountNumber { get; set; }
    public string PhoneNumber { get; set; }
    public string UserId { get; set; }
    public DateTime Timestamp { get; set; }

    public override string ToString()
    {
        return String.Format("Status: {0}, Effective Date: {1}", Status, EffectiveDate);
    }
}

[DataContract]
public class One900FeatureUpdateRequest : FeatureUpdateRequest
{
    [DataMember]
    public bool PerformSwitchUpdate { get; set; }
}

Yesterday I swear I was able to submit POST data of this form:

<One900FeatureUpdateRequest>
  <EffectiveDate>1999-05-31T11:20:00</EffectiveDate>
  <Status>Enabled</Status>
  <PerformSwitchUpdate>true</PerformSwitchUpdate>
</One900FeatureUpdateRequest>

Today that same batch of XML is causing HTTP 400 errors with the following message:

Unable to deserialize XML body with root name 'One900FeatureUpdateRequest' and root namespace '' (for operation 'UpdateFeatureStatus' and contract ('IPhoneFeaturesManagementHost',  'http://tempuri.org/')) using DataContractSerializer. Ensure that the type corresponding to the XML is added to the known types collection of the service.

The only XML that seems to work today is the below, and I really really dislike the necessity of adding a namespace plus attribute to describe the subtype of my child DataContract.

<FeatureUpdateRequest i:type="One900FeatureUpdateRequest" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Project.Services.Host">
  <EffectiveDate>1999-05-31T11:20:00</EffectiveDate>
  <Status>Enabled</Status>
  <PerformSwitchUpdate>true</PerformSwitchUpdate>
</FeatureUpdateRequest>

Does anyone have any ideas as to what I might have touched or what I might need to change in order to get back to the prior simple XML format for deserialization?

Any help would be much appreciated. Thanks!

like image 821
Paul Kirby Avatar asked Nov 13 '22 16:11

Paul Kirby


1 Answers

I couldn't find a way to do this with the DataContractSerializer, so I instead switched to the old XmlSerializer so I can have direct control over the XML format. This seemed to work.

like image 121
Paul Kirby Avatar answered Dec 22 '22 08:12

Paul Kirby