การเปลี่ยน serializer เป็นเรื่องง่ายหากคุณใช้ Web API แต่น่าเสียดายที่ MVC ใช้JavaScriptSerializer
โดยไม่มีตัวเลือกในการเปลี่ยนสิ่งนี้เพื่อใช้ JSON.Net
คำตอบของ Jamesและคำตอบของ Danielทำให้ JSON.Net มีความยืดหยุ่น แต่หมายความว่าทุกที่ที่ปกติreturn Json(obj)
คุณจะต้องเปลี่ยนreturn new JsonNetResult(obj)
หรือคล้ายกันซึ่งหากคุณมีโปรเจ็กต์ขนาดใหญ่สามารถพิสูจน์ปัญหาได้และยังไม่ยืดหยุ่นมากหาก คุณเปลี่ยนใจกับ Serializer ที่คุณต้องการใช้
ฉันตัดสินใจไปตามActionFilter
เส้นทางแล้ว โค้ดด้านล่างช่วยให้คุณดำเนินการใด ๆ โดยใช้JsonResult
และใช้แอตทริบิวต์เพื่อใช้ JSON.Net (พร้อมคุณสมบัติตัวพิมพ์เล็ก):
[JsonNetFilter]
[HttpPost]
public ActionResult SomeJson()
{
return Json(new { Hello = "world" });
}
คุณยังสามารถตั้งค่านี้ให้ใช้กับการกระทำทั้งหมดโดยอัตโนมัติได้ด้วย (ด้วยการis
ตรวจสอบประสิทธิภาพเล็กน้อยเท่านั้น):
FilterConfig.cs
filters.Add(new JsonNetFilterAttribute());
รหัส
public class JsonNetFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Result is JsonResult == false)
return;
filterContext.Result = new CustomJsonResult((JsonResult)filterContext.Result);
}
private class CustomJsonResult : JsonResult
{
public CustomJsonResult(JsonResult jsonResult)
{
this.ContentEncoding = jsonResult.ContentEncoding;
this.ContentType = jsonResult.ContentType;
this.Data = jsonResult.Data;
this.JsonRequestBehavior = jsonResult.JsonRequestBehavior;
this.MaxJsonLength = jsonResult.MaxJsonLength;
this.RecursionLimit = jsonResult.RecursionLimit;
}
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
throw new ArgumentNullException("context");
if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet
&& String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
throw new InvalidOperationException("GET not allowed! Change JsonRequestBehavior to AllowGet.");
var response = context.HttpContext.Response;
response.ContentType = String.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType;
if (this.ContentEncoding != null)
response.ContentEncoding = this.ContentEncoding;
if (this.Data != null)
{
var json = JsonConvert.SerializeObject(
this.Data,
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
response.Write(json);
}
}
}
}