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

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

作为一个例子,考虑下面的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"
}

我怎么做呢?

194672 次浏览

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

或者,简单地说:

JsonConvert.SerializeObject(
<YOUR OBJECT>,
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});

例如:

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

下面是一个动作方法,通过序列化一个对象数组返回一个json字符串(cameCase)。

public string GetSerializedCourseVms()
{
var courses = new[]
{
new CourseVm{Number = "CREA101", Name = "Care of Magical Creatures", Instructor ="Rubeus Hagrid"},
new CourseVm{Number = "DARK502", Name = "Defence against dark arts", Instructor ="Severus Snape"},
new CourseVm{Number = "TRAN201", Name = "Transfiguration", Instructor ="Minerva McGonal"}
};
var camelCaseFormatter = new JsonSerializerSettings();
camelCaseFormatter.ContractResolver = new CamelCasePropertyNamesContractResolver();
return JsonConvert.SerializeObject(courses, camelCaseFormatter);
}

注意作为第二个参数传递的JsonSerializerSettings实例。这就是骆驼案发生的原因。

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

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

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

我想这就是你想要的简单答案。它来自肖恩Wildermuth的博客:

// Add MVC services to the services container.
services.AddMvc()
.AddJsonOptions(opts =>
{
opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});

自定义过滤器的另一种选择是创建一个扩展方法,将任何对象序列化为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");

在ASP。NET核心MVC。

    public IActionResult Foo()
{
var data = GetData();


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


return Json(data, settings);
}

我是这样做的:

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的能力,当然这取决于:)

在我看来越简单越好!

你为什么不这样做呢?

public class CourseController : JsonController
{
public ActionResult ManageCoursesModel()
{
return JsonContent(<somedata>);
}
}

简单基类控制器

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

您必须在“Startup.cs”文件中设置设置

您还必须在JsonConvert的默认值中定义它,这是如果您以后想直接使用库来序列化对象。

    public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddJsonOptions(options => {
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
}

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

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

[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

安装包Microsoft.AspNetCore.Mvc.NewtonsoftJson

这解决了我的问题