2011-01-25 20 views
7

Phil Haack, JSON, veri bağlama ve veri doğrulamanın nasıl kullanılacağı konusunda mükemmel bir blog post sahiptir.ASP.NET MVC 3 JSONP: Bu JsonValueProviderFactory ile çalışır mı?

Tarayıcının "aynı kaynak politikası güvenlik kısıtlaması" nı girin. ve içeriği almak için $ .getJSON() kullandığınız JSONP.

Bunu yapmak için MVC 3 yolunda bir yer var mı, yoksa posts like this'un önerisine uymalı mıyım? İçerik yayınlayabilir misiniz? Bunu soruyorum çünkü meslektaşım bu işi yapmak için başka şeylerin yanı sıra bir JsonPfilterAttribute uyguladı. Açıkçası önlemek için tercih ediyor bir şeylerin zaten MVC bulunuyorsa 3.

Düzenleme:

Özet: her şey içinde POST değişken erişmek nasıl bir POST değişken erişim istisna, yani çalışır bağlam?

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

bu yanıtı üretir:

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

Ve tüm bu işleri

Sunucu çağırmak için bu formatı kullanmaya seçildi (yorum kodunun son bölümünde işaretleyerek) GET kullanıyorum çok iyi. Ancak, hala bu bir POST olarak çalışmak için alamıyorum. İşte Nathan Bridgewater tarafından yayınlanan orijinal kod here. Bu çizgi POST verileri bulmaz:

context.HttpContext.Request["callback"]; 

Ya bir şekilde Form erişen edilecek yoksa MVC veri doğrulayıcılar POST değişkenleri dışarı sıyırma edilir.

POST değişkenine erişmek için context.HttpContext.Request["callback"]; nasıl yazılmalı veya MVC bu değerleri herhangi bir nedenle sıyırma amaçlı mıdır?

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

cevap

39

Bildiğim kadarıyla bir JSON dize alma ve JsonValueProviderFactory konusu olduğunda bir model için bağlayıcı olarak ASP.NET MVC 3'te kutunun dışında bu işi yapar ama yerleşik JSONP çıkışı için hiçbir şey yoktur. Denetleyiciniz eylem ardından

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

Ve: Bir özel JsonpResult yazabilirsiniz

$.getJSON() ile başka bir alandan tüketilebilecek
public ActionResult Foo() 
{ 
    return new JsonpResult 
    { 
     Data = new { Prop1 = "value1", Prop2 = "value2" }, 
     JsonRequestBehavior = JsonRequestBehavior.AllowGet 
    }; 
} 

:

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

ben yansıtmak için soru düzenlenebilir Cevabınız (güzel cevap), sadece bir parça daha çalışmaya ihtiyacınız var. –

+2

@Dr. Zim, JSONP, jQuery tarafından uygulanan GET istekleriyle çalışır. Burada sihir yoktur, jQuery, uzak sunucuya işaret eden barındırma sayfasının DOM'sine bir "