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

本文关键字:DefaultContractResolver JSON NET 自定义 我的 在哪里 插入 我应该 | 更新日期: 2023-09-27 18:11:17

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

谢谢!

---编辑2014年7月3日我已经知道如何通过创建一个新的ConfigSettings对象并手动解析该对象来使用我的自定义实现;但是,生成的JSON被序列化了两次(它有额外的字符(。这是因为webAPI控制器默认情况下会序列化响应,所以我想更改以覆盖该行为。。。这是正确的路吗?

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

我自己刚刚经历了解决这个问题的痛苦,我需要一个能满足每个请求的解决方案。您可以使用这种方法,只返回相同的媒体格式化程序。我发现在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 = <YourContractResolverInstance>;
    return formatter;
}
}

我想你已经弄清楚了这一部分,但你的合同解析器可以覆盖"CreateProperties",并让你自己的逻辑来决定将出现什么json属性以及它们将使用什么名称(为了完整性和其他读者的利益而添加(:

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

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

Asume我们有一个简单的Foo类:

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

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

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

请注意,该框架自动将Foo序列化为JSON。

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

// GET api/Foo
public HttpResponseMessage GetFoos()
{
    var foos = GetAListOfFoosFromSomewhere(); //returns an IQueryable<Foo>
    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;
}

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

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

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

相关文章:
  • 没有找到相关文章