我的问题是,我希望返回camelcases(而不是标准PascalCase) JSON数据通过ActionResults从ASP。NET MVC控制器方法,由JSON.NET序列化。

作为一个例子,考虑下面的c#类:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

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

{
  "FirstName": "Joe",
  "LastName": "Public"
}

我希望它被序列化(由JSON.NET)为:

{
  "firstName": "Joe",
  "lastName": "Public"
}

我怎么做呢?


当前回答

我在Mats Karlsson的博客上找到了一个很好的解决方法。解决方案是编写ActionResult的子类,通过JSON序列化数据。NET,将后者配置为遵循camelCase约定:

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控制器方法中像下面这样使用这个类:

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

其他回答

我是这样做的:

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核心中一个简单的扩展方法,它会给你项目中的每个对象ToJson()能力,在我看来,在一个MVC项目中,大多数对象应该有成为json的能力,当然这取决于:)

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

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);
    }
}

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

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

将Json NamingStrategy属性添加到类定义中。

[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))] 公共阶层人 { public string FirstName {get;设置;} 公共字符串LastName {get;设置;} }

对于WebAPI,请查看这个链接: http://odetocode.com/blogs/scott/archive/2013/03/25/asp-net-webapi-tip-3-camelcasing-json.aspx

基本上,添加以下代码到你的Application_Start:

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

如果你在。net core web api中返回ActionResult,或IHttpAction结果,那么你可以用Ok()方法包装你的模型,该方法将匹配你前端的情况并为你序列化它。不需要使用JsonConvert。:)