Учитывая следующий класс,
public class Result
{
public bool Success { get; set; }
public string Message { get; set; }
}
Я возвращаю один из них в действии контроллера, например,
return Json(new Result() { Success = true, Message = "test"})
Однако моя клиентская среда ожидает, что эти свойства будут строчными буквами успеха и сообщения. На самом деле, без необходимости иметь имена свойств в нижнем регистре, является ли способ реализовать эту мысль обычным вызовом функции Json?
asp.net-mvc
json
Джеймс Хьюз
источник
источник
Изменить сериализатор просто, если вы используете веб-API, но, к сожалению, сам MVC использует
JavaScriptSerializer
без возможности изменить это для использования JSON.Net.Ответ Джеймса и ответ Даниэля дать вам гибкость JSON.Net , но означает , что везде , где вы обычно делаете ,
return Json(obj)
вы должны изменить кreturn new JsonNetResult(obj)
или аналогичный , который , если у вас есть большой проект может оказаться проблемой, а также не очень гибким , если вы передумали о сериализаторе, который хотите использовать.Решил пойти по
ActionFilter
маршруту. Приведенный ниже код позволяет вам выполнять любое действие, используяJsonResult
и просто применять к нему атрибут для использования JSON.Net (со свойствами нижнего регистра):[JsonNetFilter] [HttpPost] public ActionResult SomeJson() { return Json(new { Hello = "world" }); } // outputs: { "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); } } } }
источник
С моим решением вы можете переименовать любое свойство, какое захотите.
Я нашел часть решения здесь и на SO
public class JsonNetResult : ActionResult { public Encoding ContentEncoding { get; set; } public string ContentType { get; set; } public object Data { get; set; } public JsonSerializerSettings SerializerSettings { get; set; } public Formatting Formatting { get; set; } public JsonNetResult(object data, Formatting formatting) : this(data) { Formatting = formatting; } public JsonNetResult(object data):this() { Data = data; } public JsonNetResult() { Formatting = Formatting.None; SerializerSettings = new JsonSerializerSettings(); } public override void ExecuteResult(ControllerContext context) { if (context == null) throw new ArgumentNullException("context"); var response = context.HttpContext.Response; response.ContentType = !string.IsNullOrEmpty(ContentType) ? ContentType : "application/json"; if (ContentEncoding != null) response.ContentEncoding = ContentEncoding; if (Data == null) return; var writer = new JsonTextWriter(response.Output) { Formatting = Formatting }; var serializer = JsonSerializer.Create(SerializerSettings); serializer.Serialize(writer, Data); writer.Flush(); } }
Так что в моем контроллере я могу это сделать
return new JsonNetResult(result);
В моей модели теперь могут быть:
[JsonProperty(PropertyName = "n")] public string Name { get; set; }
Обратите внимание, что теперь вы должны установить
JsonPropertyAttribute
для каждого свойства, которое хотите сериализовать.источник
Хотя это старый вопрос, надеюсь, что приведенный ниже фрагмент кода будет полезен другим,
Я сделал это ниже с помощью веб-API MVC5.
public JsonResult<Response> Post(Request request) { var response = new Response(); //YOUR LOGIC IN THE METHOD //....... //....... return Json<Response>(response, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver() }); }
источник
Вы можете добавить эту настройку в
Global.asax
, и она будет работать везде.public class Global : HttpApplication { void Application_Start(object sender, EventArgs e) { //.... JsonConvert.DefaultSettings = () => { var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), PreserveReferencesHandling = PreserveReferencesHandling.None, Formatting = Formatting.None }; return settings; }; //.... } }
источник