Asp.net-Mvc

MVC JsonResult camelCase序列化[重複]

  • February 23, 2013

我試圖讓我的操作返回一個 JsonResult,它的所有屬性都在 camelCase 中。

我有一個簡單的模型:

public class MyModel
{
   public int SomeInteger { get; set; }

   public string SomeString { get; set; }
}

還有一個簡單的控制器動作:

public JsonResult Index()
   {
       MyModel model = new MyModel();
       model.SomeInteger = 1;
       model.SomeString = "SomeString";

       return Json(model, JsonRequestBehavior.AllowGet);
   }

現在呼叫此操作方法會返回一個包含以下數據的 JsonResult:

{"SomeInteger":1,"SomeString":"SomeString"}

對於我的用途,我需要該操作以 camelCase 格式返回數據,如下所示:

{"someInteger":1,"someString":"SomeString"}

有什麼優雅的方法可以做到這一點嗎?

我在這裡尋找可能的解決方案,發現MVC3 JSON 序列化:如何控制屬性名稱?他們將 DataMember 定義設置為模型的每個屬性,但我真的不想這樣做。

我還找到了一個連結,他們說可以完全解決這類問題:http ://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-序列化#json_camelcasing。它說:

要使用駝峰式大小寫編寫 JSON 屬性名稱,而不更改數據模型,請在序列化程序上設置 CamelCasePropertyNamesContractResolver:

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

此部落格<http://frankapi.wordpress.com/2012/09/09/going-camelcase-in-asp-net-mvc-web-api/>上的一個條目也提到了此解決方案,並聲明您可以簡單地將其添加到RouteConfig.RegisterRoutes來解決這個問題。我試過了,但我無法讓它工作。

你們知道我在哪裡做錯了嗎?

Controller 的 Json 函式只是用於創建 JsonResults 的包裝器:

protected internal JsonResult Json(object data)
{
   return Json(data, null /* contentType */, null /* contentEncoding */, JsonRequestBehavior.DenyGet);
}

protected internal JsonResult Json(object data, string contentType)
{
   return Json(data, contentType, null /* contentEncoding */, JsonRequestBehavior.DenyGet);
}

protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding)
{
   return Json(data, contentType, contentEncoding, JsonRequestBehavior.DenyGet);
}

protected internal JsonResult Json(object data, JsonRequestBehavior behavior)
{
   return Json(data, null /* contentType */, null /* contentEncoding */, behavior);
}

protected internal JsonResult Json(object data, string contentType, JsonRequestBehavior behavior)
{
   return Json(data, contentType, null /* contentEncoding */, behavior);
}

protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
{
   return new JsonResult
   {
       Data = data,
       ContentType = contentType,
       ContentEncoding = contentEncoding,
       JsonRequestBehavior = behavior
   };
}

JsonResult 內部使用 JavaScriptSerializer,因此您無法控制序列化過程:

public class JsonResult : ActionResult
{
   public JsonResult()
   {
       JsonRequestBehavior = JsonRequestBehavior.DenyGet;
   }

   public Encoding ContentEncoding { get; set; }

   public string ContentType { get; set; }

   public object Data { get; set; }

   public JsonRequestBehavior JsonRequestBehavior { get; set; }

   /// &lt;summary&gt;
   /// When set MaxJsonLength passed to the JavaScriptSerializer.
   /// &lt;/summary&gt;
   public int? MaxJsonLength { get; set; }

   /// &lt;summary&gt;
   /// When set RecursionLimit passed to the JavaScriptSerializer.
   /// &lt;/summary&gt;
   public int? RecursionLimit { 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(MvcResources.JsonRequest_GetNotAllowed);
       }

       HttpResponseBase response = context.HttpContext.Response;

       if (!String.IsNullOrEmpty(ContentType))
       {
           response.ContentType = ContentType;
       }
       else
       {
           response.ContentType = "application/json";
       }
       if (ContentEncoding != null)
       {
           response.ContentEncoding = ContentEncoding;
       }
       if (Data != null)
       {
           JavaScriptSerializer serializer = new JavaScriptSerializer();
           if (MaxJsonLength.HasValue)
           {
               serializer.MaxJsonLength = MaxJsonLength.Value;
           }
           if (RecursionLimit.HasValue)
           {
               serializer.RecursionLimit = RecursionLimit.Value;
           }
           response.Write(serializer.Serialize(Data));
       }
   }
}

您必須創建自己的 JsonResult 並編寫自己的 Json 控制器函式(如果需要/想要的話)。您可以創建新的或覆蓋現有的,這取決於您。您可能也會對此連結感興趣。

如果您想從您的操作中返回一個遵循駝峰表示法的 json 字元串,您必須創建一個 JsonSerializerSettings 實例並將其作為 JsonConvert.SerializeObject(a,b) 方法的第二個參數傳遞。

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

引用自:https://stackoverflow.com/questions/15040838