我应该在哪里插入我的自定义DefaultContractResolver JSON.NET?

我在ASP.Net中有一个WebAPI 2.0项目,我在其中实现了一个自定义的DefaultContractResolver,这样我就可以控制我的实体如何使用JSON.Net序列化为JSON; 但我不确定如何告诉框架使用我的自定义实现。 我还想知道是否可以为特定的控制器/操作更改ContractResolver。

谢谢!

—编辑03/07/2014我已经通过创建一个新的ConfigSettings对象并手动解析对象,已经找到了如何使用我的自定义实现; 但是,生成的JSON被序列化两次(它有额外的\ r \ n字符)。 这是因为webAPI控制器默认序列化响应,所以我想更改以覆盖该行为……这是正确的方法吗?

我只是经历了弄清楚自己的痛苦,我需要一个按照要求工作的。 您可以使用该方法并返回相同的媒体格式化程序。 我发现在GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ContractResolver上设置一个格式化程序对于每个请求的需求有点不可靠,即使我尝试在该类的单个实例中处理每个请求的需求。 但是,您可以尝试在App_Start代码中的某处设置ContractResolver实例

我最终创建了一个自定义的JsonMediaTypeFormatter ,它检查是否有一个为请求配置的ContractResolver,你可以只返回一个和同一个解析器:

 public class DynamicJsonMediaTypeFormatter : JsonMediaTypeFormatter { public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, System.Net.Http.HttpRequestMessage request, System.Net.Http.Headers.MediaTypeHeaderValue mediaType) { // shown is getting the current formatter, but you can return an instance you prefer var formatter = base.GetPerRequestFormatterInstance(type, request, mediaType) as JsonMediaTypeFormatter; // Here I had more code to get the resolver based on request, skipped ((JsonMediaTypeFormatter)formatter).SerializerSettings.ContractResolver = ; return formatter; } } 

我认为你已经想出了那个部分,但是你的合同解析器可以覆盖`CreateProperties’并且有你自己的逻辑决定将出现什么json属性以及它们将使用什么名称(为了其他读者的完整性和好处而添加):

 public class DynamicContractResolver : DefaultContractResolver { ... protected override IList CreateProperties(Type type, MemberSerialization memberSerialization){ ... } 

我最终改变了我的方法的返回类型,如下所示:

假设我们有这个简单的Foo类:

 public class Foo { public string Bar {get; set;} } 

使用ASP WebApi 2.0,GET的脚手架控制器方法如下所示:

 // GET api/Foo public IQueryable GetFoos() { var foos = GetAListOfFoosFromSomewhere() //returns an IQueryable return Foos } 

请注意,框架会自动将Foos序列化为JSON。

所以我做的是将方法更改为:

 // GET api/Foo public HttpResponseMessage GetFoos() { var foos = GetAListOfFoosFromSomewhere(); //returns an IQueryable var settings = new JsonSerializerSettings() { ContractResolver= new MyCustomContractResolver(), //Put your custom implementation here //Also set up ReferenceLoopHandling as appropiate }; var jsoncontent = JsonConvert.SerializeObject(foos, settings); var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(jsoncontent, Encoding.UTF8, "application/json") }; return response; } 

在我的解决方案中,我添加了一个convience方法来创建HttpResponseMessage,所以看起来有点像这样:

 public HttpResponseMessage GetFoos() { var foos = GetAListOfFoosFromSomewhere() //returns an IQueryable return CreateResponse(foos); } 

由mercury2269撰写的这篇文章真的很有帮助。