2011-01-25 25 views
7

Phil Haack có blog post tuyệt vời về cách sử dụng JSON, ràng buộc dữ liệu và xác thực dữ liệu.ASP.NET MVC 3 JSONP: Tính năng này có hoạt động với JsonValueProviderFactory không?

Nhập "hạn chế bảo mật chính sách gốc của cùng một trình duyệt" của trình duyệt. và JSONP nơi bạn sử dụng $ .getJSON() để truy xuất nội dung.

Có cách nào được xây dựng theo MVC 3 để thực hiện việc này hay tôi có cần làm theo lời khuyên của posts like this không? Bạn có thể đăng nội dung không? Tôi hỏi vì đồng nghiệp của tôi đã triển khai một JsonPfilterAttribute trong số những thứ khác để thực hiện công việc này. Nó rõ ràng là ưu tiên để tránh rằng nếu một cái gì đó đã tồn tại trong MVC 3.

Edit:

Tóm tắt: mọi thứ hoạt động ngoại trừ truy cập vào một biến POST, tức là, làm thế nào để truy cập vào biến POST trong bối cảnh? (comment đánh dấu nó trong phần cuối cùng của mã)

tôi được bầu vào sử dụng định dạng này để gọi máy chủ:

$.ajax({ 
    type: "GET", 
    url: "GetMyDataJSONP", 
    data: {}, 
    contentType: "application/json; charset=utf-8", 
    dataType: "jsonp", 
    jsonpCallback: "randomFunctionName" 
}); 

nào tạo ra phản ứng này:

randomFunctionName([{"firstField":"111","secondField":"222"}]); 

Và tất cả các công trình này rất tốt nếu tôi sử dụng GET. Tuy nhiên, tôi vẫn không thể làm điều này để làm việc như một POST. Đây là mã gốc được đăng bởi Nathan Bridgewater here. Dòng này không tìm thấy dữ liệu POST:

context.HttpContext.Request["callback"]; 

Hoặc là tôi nên được truy cập Form một cách nào đó, hoặc xác nhận dữ liệu MVC được tước ra các biến POST.

Làm thế nào nên context.HttpContext.Request["callback"]; được viết để truy cập biến số POST hoặc là MVC tước các giá trị này vì một lý do nào đó?

namespace System.Web.Mvc 
{ public class JsonpResult : ActionResult 
    { public JsonpResult() {} 

     public Encoding ContentEncoding { get; set; } 
     public string ContentType { get; set; } 
     public object Data { get; set; } 
     public string JsonCallback { get; set; } 

     public override void ExecuteResult(ControllerContext context) 
     { if (context == null) 
       throw new ArgumentNullException("context"); 

      this.JsonCallback = context.HttpContext.Request["jsoncallback"]; 

      // This is the line I need to alter to find the form variable: 

      if (string.IsNullOrEmpty(this.JsonCallback)) 
       this.JsonCallback = context.HttpContext.Request["callback"]; 

      if (string.IsNullOrEmpty(this.JsonCallback)) 
       throw new ArgumentNullException(
        "JsonCallback required for JSONP response."); 

      HttpResponseBase response = context.HttpContext.Response; 

      if (!String.IsNullOrEmpty(ContentType)) 
       response.ContentType = ContentType; 
      else 
       response.ContentType = "application/json; charset=utf-8"; 

      if (ContentEncoding != null) 
       response.ContentEncoding = ContentEncoding; 

      if (Data != null) 
      { JavaScriptSerializer serializer = new JavaScriptSerializer(); 
       response.Write(string.Format("{0}({1});", this.JsonCallback, 
        serializer.Serialize(Data))); 
    } } } 

    //extension methods for the controller to allow jsonp. 
    public static class ContollerExtensions 
    { 
     public static JsonpResult Jsonp(this Controller controller, 
       object data) 
     { 
      JsonpResult result = new JsonpResult(); 
      result.Data = data; 
      result.ExecuteResult(controller.ControllerContext); 
      return result; 
     } 
    } 
} 

Trả lời

39

Theo như nhận một chuỗi JSON và ràng buộc nó vào một mô hình là có liên quan các JsonValueProviderFactory làm công việc này ra khỏi hộp trong ASP.NET MVC 3. Nhưng không có gì built-in cho outputting JSONP là. Bạn có thể viết một tùy chỉnh JsonpResult:

public class JsonpResult : JsonResult 
{ 
    public override void ExecuteResult(ControllerContext context) 
    { 
     if (context == null) 
     { 
      throw new ArgumentNullException("context"); 
     } 
     var request = context.HttpContext.Request; 
     var response = context.HttpContext.Response; 
     string jsoncallback = (context.RouteData.Values["jsoncallback"] as string) ?? request["jsoncallback"]; 
     if (!string.IsNullOrEmpty(jsoncallback)) 
     { 
      if (string.IsNullOrEmpty(base.ContentType)) 
      { 
       base.ContentType = "application/x-javascript"; 
      } 
      response.Write(string.Format("{0}(", jsoncallback)); 
     } 
     base.ExecuteResult(context); 
     if (!string.IsNullOrEmpty(jsoncallback)) 
     { 
      response.Write(")"); 
     } 
    } 
} 

Và sau đó trong hành động điều khiển của bạn:

public ActionResult Foo() 
{ 
    return new JsonpResult 
    { 
     Data = new { Prop1 = "value1", Prop2 = "value2" }, 
     JsonRequestBehavior = JsonRequestBehavior.AllowGet 
    }; 
} 

mà có thể được tiêu thụ từ miền khác với $.getJSON():

$.getJSON('http://domain.com/home/foo?jsoncallback=?', function(data) { 
    alert(data.Prop1); 
}); 
+0

Tôi chỉnh sửa các câu hỏi để phản ánh câu trả lời của bạn (câu trả lời hay), chỉ cần thêm một tác phẩm nữa. –

+2

@Dr. Zim, 'JSONP' chỉ hoạt động với các yêu cầu GET được thực thi bởi jQuery. Không có phép thuật ở đây, jQuery chỉ cần tiêm một thẻ '

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