ASP.NET MVC 3 JSONP: ¿Funciona esto con JsonValueProviderFactory?

Phil Haack tiene una excelente publicación en el blog sobre cómo usar JSON, el enlace de datos y la validación de datos.

Ingrese la “misma restricción de seguridad de la política de origen” del navegador. y JSONP donde usa $ .getJSON () para recuperar el contenido.

¿Hay una forma incorporada de MVC 3 para hacer esto, o tengo que seguir el consejo de publicaciones como esta ? ¿Puedes publicar contenido? Pregunto porque mi colega implementó un JsonPfilterAttribute entre otras cosas para que esto funcione. Obviamente es preferible evitar eso si algo ya existe en MVC 3.

Editar:

Resumen: todo funciona con la excepción de acceder a una variable POST , es decir, ¿cómo POST variable POST en el contexto? (comentario marcándolo en la última sección del código)

Elegí usar este formato para llamar al servidor:

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

Que produce esta respuesta:

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

Y todo esto funciona muy bien si uso un GET . Sin embargo, todavía no puedo hacer que funcione como POST . Aquí está el código original publicado por Nathan Bridgewater aquí . Esta línea no encuentra los datos POST:

 context.HttpContext.Request["callback"]; 

O debería estar accediendo al Form de alguna forma, o los validadores de datos MVC están eliminando las variables POST.

¿Cómo debería context.HttpContext.Request["callback"]; ¿se escribe para acceder a la variable POST o MVC elimina estos valores por alguna razón?

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

En lo que respecta a recibir una cadena JSON y vincularla a un modelo, JsonValueProviderFactory realiza este trabajo de JsonValueProviderFactory en ASP.NET MVC 3. Pero no hay nada incorporado para generar JSONP. Podría escribir un JsonpResult personalizado:

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

Y luego en su acción de controlador:

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

que podría ser consumido desde otro dominio con $.getJSON() :

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