2011-07-30 16 views
17

Tôi có một bộ điều khiển trả về các đối tượng JSON lớn cho jQuery Flot và tôi đã tự hỏi làm thế nào để thay thế JavaScriptSerializer mặc định bằng một cái gì đó nhanh hơn như một từ ServiceStack.Text.Thay đổi serializer mặc định JSON được sử dụng trong ASP MVC3

Sẽ tốt nếu tôi có thể thay đổi nội dung như thế này bằng cách sử dụng DependencyResolver, nhưng tôi cho rằng nếu mọi thứ đã được giải quyết xong thì nó có thể khá chậm.

+0

liên quan: http://stackoverflow.com/questions/7109967/using-json-net-as-default-json-serializer-in-asp-net-mvc-3-is-it-possible –

+1

Tôi đã hỏi điều này câu hỏi 2 tuần trước khi liên kết trùng lặp ... Điều đó làm cho câu hỏi khác trùng lặp! – Tim

Trả lời

40

đặt cược tốt nhất của bạn là để kế thừa từ lớp JsonResult và ghi đè Thực hiện phương pháp như

public class CustomJsonResult: JsonResult 
{ 
    public CustomJsonResult() 
    { 
     JsonRequestBehavior = JsonRequestBehavior.DenyGet; 
    } 
    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) { 
       CustomJsSerializer serializer = new CustomJsSerializer(); 
       response.Write(serializer.Serialize(Data)); 
      } 
     } 
} 

code được lấy từ JsonResult lớp của MVC3 và thay đổi dòng này

JavaScriptSerializer serializer = new JavaScriptSerializer(); 

để

CustomJsSerializer serializer = new CustomJsSerializer(); 

bạn có thể sử dụng lớp này theo phương thức hành động như

public JsonResult result() 
{ 
    var model = GetModel(); 
    return new CustomJsonResult{Data = model}; 
} 

Ngoài ra bạn có thể ghi đè phương pháp json của lớp điều khiển trong điều khiển cơ sở của bạn như

public class BaseController:Controller 
{ 
    protected internal override JsonResult Json(object data) 
     { 
      return new CustomJsonResult { Data = data }; 
     } 
} 

bây giờ nếu bạn có tất cả các bộ điều khiển của bạn từ BaseController sau đó return Json(data) sẽ gọi chương trình tuần tự của bạn. Ngoài ra còn có các tình trạng quá tải khác của phương pháp Json mà bạn có thể chọn ghi đè.

+0

Trong asp.net MVC 3 phương pháp - JsonResult Json (dữ liệu đối tượng) không phải là ảo: ( – Maxim

+6

Không, nhưng JsonResult Json (dữ liệu đối tượng, string contentType, Encoding contentEncoding) là, và một khác chỉ đại biểu ở đó. :) – asgerhallas

+3

Rõ ràng, bạn cần phải ghi đè lên một với 4 tham số: ghi đè bảo vệ JsonResult Json (dữ liệu đối tượng, chuỗi contentType, Mã hóa contentEncoding, hành vi JsonRequestBehavior) – Daniel

5

Tôi thêm câu trả lời này đơn giản chỉ vì tôi đang sử dụng giải pháp thay thế không yêu cầu ghi đè lớp System.Web.Mvc.Controller. Tôi thêm các phương thức mở rộng sau vào lớp System.Web.Mvc.Controller. "Lợi ích" duy nhất của giải pháp này là nó không yêu cầu bạn phải thay đổi lớp cơ sở của mã tạo ra các lớp Controller. Nếu không, nó có chức năng tương đương với câu trả lời được chấp nhận.

public static JsonResult ToJsonResult(this Controller controller, 
              object target, 
              string contentType, 
              Encoding contentEncoding, 
              JsonRequestBehavior behavior) 
    { 
     if (target != null) 
     { 
      if (target.GetType().HasAttribute<DataContractAttribute>()) 
      { 
       return new DataContractJsonResult() { ContentType = contentType, ContentEncoding = contentEncoding, JsonRequestBehavior = behavior, Data = target }; 
      } 
     } 
     return new JsonResult() { ContentType = contentType, ContentEncoding = contentEncoding, JsonRequestBehavior = behavior, Data = target }; 
    } 

    public static JsonResult ToJsonResult(this Controller controller, object target) 
    { 
     return controller.ToJsonResult(target, null, null, JsonRequestBehavior.DenyGet); 
    } 

    public static JsonResult ToJsonResult(this Controller controller, object target, string contentType) 
    { 
     return controller.ToJsonResult(target, contentType, null, JsonRequestBehavior.DenyGet); 
    } 

    public static JsonResult ToJsonResult(this Controller controller, object target, string contentType, Encoding contentEncoding) 
    { 
     return controller.ToJsonResult(target, contentType, contentEncoding, JsonRequestBehavior.DenyGet); 
    } 

    public static JsonResult ToJsonResult(this Controller controller, object target, string contentType, JsonRequestBehavior behavior) 
    { 
     return controller.ToJsonResult(target, contentType, null, behavior); 
    } 

Trong ứng dụng của mình, tôi ghi đè trình điều khiển mặc định và sử dụng bộ nối tiếp JSON.NET nếu loại có thuộc tính DataContract. Chức năng này được đóng gói trong lớp DataContractJsonResult, không được bao gồm, nhưng được mô hình hóa sau lớp trong câu trả lời được chấp nhận cho câu hỏi này.

Các vấn đề liên quan