如何从ASP.NET MVC控制器方法返回JSON.NET序列化的camelCase JSON?

How can I return camelCase JSON serialized by JSON.NET from ASP.NET MVC controller methods?

我的问题是,我希望通过ASP.NET MVC控制器方法的actionResults返回cameCased(而不是标准的pascalcase)JSON数据,该方法由json.net序列化。

例如,考虑以下C类:

1
2
3
4
5
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

默认情况下,当从MVC控制器中将此类的实例作为JSON返回时,它将按以下方式序列化:

1
2
3
4
{
 "FirstName":"Joe",
 "LastName":"Public"
}

我希望它(通过json.net)序列化为:

1
2
3
4
{
 "FirstName":"Joe",
 "LastName":"Public"
}

我该怎么做?


或者,简单地说:

1
2
3
4
5
6
JsonConvert.SerializeObject(
    <YOUR OBJECT>,
    new JsonSerializerSettings
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver()
    });

例如:

1
2
3
4
5
6
return new ContentResult
{
    ContentType ="application/json",
    Content = JsonConvert.SerializeObject(new { content = result, rows = dto }, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }),
    ContentEncoding = Encoding.UTF8
};


我在MatsKarlsson的博客上找到了一个很好的解决方案。解决方案是编写一个子类actionresult,该子类通过json.net序列化数据,并将后者配置为遵循camelcase约定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class JsonCamelCaseResult : ActionResult
{
    public JsonCamelCaseResult(object data, JsonRequestBehavior jsonRequestBehavior)
    {
        Data = data;
        JsonRequestBehavior = jsonRequestBehavior;
    }

    public Encoding ContentEncoding { get; set; }

    public string ContentType { get; set; }

    public object Data { get; set; }

    public JsonRequestBehavior JsonRequestBehavior { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && String.Equals(context.HttpContext.Request.HttpMethod,"GET", StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException("This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.");
        }

        var response = context.HttpContext.Response;

        response.ContentType = !String.IsNullOrEmpty(ContentType) ? ContentType :"application/json";
        if (ContentEncoding != null)
        {
            response.ContentEncoding = ContentEncoding;
        }
        if (Data == null)
            return;

        var jsonSerializerSettings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
        response.Write(JsonConvert.SerializeObject(Data, jsonSerializerSettings));
    }
}

然后在MVC控制器方法中使用如下类:

1
2
3
4
public ActionResult GetPerson()
{
    return new JsonCamelCaseResult(new Person { FirstName ="Joe", LastName ="Public" }, JsonRequestBehavior.AllowGet)};
}


For WebAPI, check out this link:
http://odetocode.com/blogs/scott/archive/2013/03/25/asp-net-webapi-tip-3-camelcasing-json.aspx

Basically, add this code to your Application_Start:

1
2
3
4
var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();


我想这是你要找的简单答案。这是肖恩·威尔德茅斯的博客:

1
2
3
4
5
6
// Add MVC services to the services container.
services.AddMvc()
  .AddJsonOptions(opts =>
  {
    opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
  });


自定义过滤器的另一种选择是创建一个扩展方法来将任何对象序列化为JSON。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static class ObjectExtensions
{
    /// <summary>Serializes the object to a JSON string.</summary>
    /// <returns>A JSON string representation of the object.</returns>
    public static string ToJson(this object value)
    {
        var settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            Converters = new List<JsonConverter> { new StringEnumConverter() }
        };

        return JsonConvert.SerializeObject(value, settings);
    }
}

然后在从控制器操作返回时调用它。

1
return Content(person.ToJson(),"application/json");


在ASP.NET核心MVC中。

1
2
3
4
5
6
7
8
9
10
11
    public IActionResult Foo()
    {
        var data = GetData();

        var settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        });

        return Json(data, settings);
    }


下面是一个通过序列化对象数组返回JSON字符串(camercase)的操作方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public string GetSerializedCourseVms()
    {
        var courses = new[]
        {
            new CourseVm{Number ="CREA101", Name ="Care of Magical Creatures", Instructor ="Rubeus Hagrid
<hr><P>在我看来,越简单越好!</P><P>你为什么不这么做?</P>10<P>简单的基类控制器</P>[cc]public class JsonController : BaseController
{
    protected ContentResult JsonContent(Object data)
    {
        return new ContentResult
        {
            ContentType ="application/json",
             Content = JsonConvert.SerializeObject(data, new JsonSerializerSettings {
              ContractResolver = new CamelCasePropertyNamesContractResolver() }),
            ContentEncoding = Encoding.UTF8
        };
    }
}

我确实喜欢这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
public static class JsonExtension
{
    public static string ToJson(this object value)
    {
        var settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            NullValueHandling = NullValueHandling.Ignore,
            ReferenceLoopHandling = ReferenceLoopHandling.Serialize
        };
        return JsonConvert.SerializeObject(value, settings);
    }
}

这是MVC核心中的一个简单扩展方法,它将为项目中的每个对象提供to json()功能,在我看来,在MVC项目中,大多数对象都应该具有成为json的能力,当然这取决于:)