Reputation: 43
I have created a class from a schema using xsd.exe. This class contains System.Xml.Serialization attributes.
I have used this class as a parameter for a web api method. I need to serialise the parameter to xml so I can validate against schema and create a Oracle xmltype. My web api method is as follows
[HttpPost]
public HttpResponseMessage Create([FromBody]MyClass obj)
I switched the default Serializer to XmlSerializer in webapi.config as follows
config.Formatters.XmlFormatter.UseXmlSerializer = true;
From the client using HttpWebRequest or WebClient I can successfully serialise (XmlSerializer) an instance of the class and post it to the web api using application/xml content type. So far so good.
However, if I try to send application/json content type the parameter object proerties at the web api is always null. The parameter itself is not null just the properties within.
I create the json content as follows
MyClass data = new MyClass();
// assign some values
string json = new JavaScriptSerializer().Serialize(data);
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(json);
The instance of the class serialises to JSON ok and contains values assigned, however, when I post the byte array, always null at web api.
I am sure it is something to do with the System.Xml.Serialization attributes in the class at the web api.
Does anyone have any suggestion on how to get around this? Ade
Update My class generated with xsd
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://Ade.interface")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://Ade.interface", IsNullable = false)]
public partial class MyClass
{
private string nameField;
/// <remarks/>
public string Name
{
get
{
return this.nameField;
}
set
{
this.nameField = value;
}
}
}
Web api
[HttpPost]
public HttpResponseMessage Create([FromBody]MyClass payload)
{
// payload.Name is null
}
Fiddler
POST http://myhostname/Create HTTP/1.1
Content-Type: application/json
Host: myhostname
Content-Length: 14
Expect: 100-continue
{"Name":"Ade"}
Client
string json = new JavaScriptSerializer().Serialize(data);
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(json);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://myhostname/Create");
request.Method = "POST";
request.ContentLength = bytes.Length;
request.ContentType = "application/json";
try
{
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
}
// code removed
} catch (WebException we)
{
// code removed
}
Upvotes: 0
Views: 1029
Reputation: 43
This worked for me using version="4.0.20710.0" of Microsoft.AspNet.WebApi.Core
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
json.SerializerSettings.ContractResolver = new DefaultContractResolver()
{
IgnoreSerializableInterface = true,
IgnoreSerializableAttribute = true
};
Upvotes: 1
Reputation: 57989
Based on the repro, I noticed that Json formatter works fine if your request body was rather {"nameField":"Ade"}
...
You can change this behavior by modifying the serialization settings on the contract resolver. After this change, you should be able to use {"Name":"Ade"}
Example:
JsonContractResolver resolver = (JsonContractResolver)config.Formatters.JsonFormatter.SerializerSettings.ContractResolver;
resolver.IgnoreSerializableAttribute = true; // default is 'false'
Upvotes: 0