Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET WebAPI Serialization k_BackingField Nastiness

When i serialize the following:

[Serializable] public class Error {      public string Status { get; set; }     public string Message { get; set; }     public string ErrorReferenceCode { get; set; }     public List<FriendlyError> Errors { get; set; } } 

I get this disgusting mess:

<ErrorRootOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance"   xmlns="http://schemas.datacontract.org/2004/07/Printmee.Api"> <_x003C_Errors_x003E_k__BackingField> An exception has occurred. Please contact printmee support </_x003C_Errors_x003E_k__BackingField> <_x003C_LookupCode_x003E_k__BackingField>988232ec-6bc9-48f3-8116-7ff7c71302dd</_x003C_LookupCode_x003E_k__BackingField> </ErrorRootOfstring> 

What gives? How can i make this pretty? JSON responses also contain the k_BackingField

like image 768
Micah Avatar asked Sep 08 '12 20:09

Micah


2 Answers

By default you don't need to use neither [Serializable] nor [DataContract] to work with Web API.

Just leave your model as is, and Web API would serialize all the public properties for you.

Only if you want to have more control about what's included, you then decorate your class with [DataContract] and the properties to be included with [DataMember] (because both DCS and JSON.NET respsect these attributes).

If for some reason, you need the [Serializable] on your class (i.e. you are serializing it into a memory stream for some reason, doing deep copies etc), then you have to use both attributes in conjunction to prevent the backing field names:

[Serializable] [DataContract] public class Error {     [DataMember]     public string Status { get; set; }     [DataMember]     public string Message { get; set; }     [DataMember]     public string ErrorReferenceCode { get; set; }     [DataMember]     public List<FriendlyError> Errors { get; set; } } 
like image 90
Filip W Avatar answered Sep 21 '22 08:09

Filip W


There is a more general solution: you can configure the Json Serializer to ignore the [Serializable] attribute, so that you don't have to change the attributes in your classes.

You should make this configuration change in the application start, i.e. in Global.asax Application_Start event:

var serializerSettings =   GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings; var contractResolver =   (DefaultContractResolver)serializerSettings.ContractResolver; contractResolver.IgnoreSerializableAttribute = true; 

You can also make other changes to the Json serialization, like specifying formats for serializing dates, and many other things.

This will only apply to the Web API JSON serialization. The other serializations in the app (Web API XML serialization, MVC JsonResult...) won't be affected by this setting.

like image 31
JotaBe Avatar answered Sep 20 '22 08:09

JotaBe