2

I have an existing WCF Web API app that is registering routes using the following pattern:

RouteTable.Routes.Add(new ServiceRoute("MyService", new WebServiceHostFactory(), typeof(MyServiceImplementation)));

I recently updated to Preview 6. I also updated the registration pattern in Global.asax to use the enhancements extension:

routes.SetDefaultHttpConfiguration(new MyServiceConfiguration());
routes.MapServiceRoute<MyServiceImplementation>("MyService");

I also have a contract that I am posting to a method in a request.

[WebInvoke(UriTemplate = "/MyOperation", Method = "POST")]
Contact MyOperation(Contact contact);

...

[DataContract( Name = "Contact" )]
public class Contact : IExtensibleDataObject
{
    [StringLength(50)]
    [StringNotEmpty]
    [DataMember(Name = "FirstName", Order = 1)]
    public string FirstName { get; set; }

    [DataMember(Name = "LastName", Order = 1)]
    public string LastName { get; set; }

    //[StringLength(50)]
    //[DataMember(Name = "Location", Order = 1)]
    //public String Location { get; set; }

    public ExtensionDataObject ExtensionData { get; set; }
}

The issue I am getting is that when I post a previously acceptable contract, such as:

<Contact xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://myservice/schema">
   <FirstName>John</FirstName>
   <LastName>Smith</LastName>
   <Location i:nil="true" />
</Contact>

I get the following exception:

The server encountered an error processing the request. Please see the service help page for constructing valid requests to the service. The exception message is 'The service operation 'MyOperation' expected a value assignable to type 'Contact' for input parameter 'contact' but received a value of type 'HttpRequestMessage`1'.'. See server logs for more details.

I found that if I remove the xmlns="http://myservice/schema" from my request, the service accepts the request. I have existing api clients that will be making calls to the new service with this present, so I have to make sure these messages are accepted.

I understand that the WCF Web Api Enhancements (extension method) I am using uses different classes under the hood; but I am a little ignorant at the moment as to why one would be able to deserialize and the other would not.

Cheers.

David Savage
  • 760
  • 5
  • 15

1 Answers1

2

The WCF Web API doesn use the DataContact serializer but the XmlSerializer so you will need to use those attributed to decorate your Contract class. Try adding the XmlRootAttribute with a Namespace to the Contract class.

[XmlRoot(Namespace = "http://myservice/schema")]
public class Contact 
{
   // ...
}
Maurice
  • 27,582
  • 5
  • 49
  • 62
  • That did it! So, I had read (http://codebetter.com/glennblock/2011/05/15/using-datacontracts-with-wcf-web-api/) that you could tag your contract with the [DataContractFormat] attribute to get it to use the DataContractSerializer. Any idea why that would not work? – David Savage Feb 03 '12 at 15:45
  • They have been making a lot of braking changes changes between versions. Using the element focused DataContractSerializer really doesn't make sense with a REST service. They still use the JSONDataContractSerializer though. – Maurice Feb 04 '12 at 07:58