ASP.NET MVC 3 JSONP:是否与JsonValueProviderFactory这项工作? [英] ASP.NET MVC 3 JSONP: Does this work with JsonValueProviderFactory?
问题描述
菲尔哈克具有优良的<一个href=\"http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx\">blog帖子如何使用JSON,数据绑定和数据验证。
输入浏览器的同源策略,安全限制。和JSONP在您使用$ .getJSON()来获取内容。
有一个内置的MVC 3的方式来做到这一点,或者我需要遵循的帖子这样?你可以张贴的内容?我问,因为我的同事实施了JsonPfilterAttribute除其他事项外,使这项工作。这显然preferred,以避免某些东西在MVC 3。
已存在编辑:
总结:一切工作以访问 POST
变量,即外,我怎么访问 POST
在上下文变量?(注释标记它在code最后一节)
我选择使用这种格式来调用服务器:
$。阿贾克斯({
键入:GET,
网址:GetMyDataJSONP
数据:{},
的contentType:应用/ JSON的;字符集= UTF-8,
数据类型:JSONP
jsonpCallback:randomFunctionName
});
这会产生这样的响应:
randomFunctionName([{firstField:111,secondField:222}]);
而这一切都工作得非常好,如果我使用 GET
。但是,我还是不能得到这个作为一个 POST
工作。下面是发表弥敦道布里奇沃特<一个原始的code href=\"http://www.integratedwebsystems.com/2010/07/cross-domain-jsonp-using-asp-net-mvc-and-jquery/\">here.此行没有找到POST数据:
context.HttpContext.Request [回调];
要么我应该访问表格
以某种方式,或MVC数据验证程序是剥出POST变量。
如何应 context.HttpContext.Request [回调];
写入访问 POST
变量或MVC剔除这些值由于某种原因?
命名空间System.Web.Mvc
{公共类的Json presult:的ActionResult
{公众的Json presult(){} 公共编码ContentEncoding {搞定;组; }
公共字符串的ContentType {搞定;组; }
公共对象数据{搞定;组; }
公共字符串JsonCallback {搞定;组; } 公共覆盖无效的ExecuteReuslt(ControllerContext上下文)
{如果(上下文== NULL)
抛出新的ArgumentNullException(上下文); this.JsonCallback = context.HttpContext.Request [jsoncallback]; //这是我需要改变,找到表单变量行: 如果(string.IsNullOrEmpty(this.JsonCallback))
this.JsonCallback = context.HttpContext.Request [回调]; 如果(string.IsNullOrEmpty(this.JsonCallback))
抛出新的ArgumentNullException(
需要JSONP响应JsonCallback。); HTT presponseBase响应= context.HttpContext.Response; 如果(!String.IsNullOrEmpty(的ContentType))
response.ContentType = ContentType的;
其他
response.ContentType =应用/ JSON的;字符集= UTF-8; 如果(ContentEncoding!= NULL)
response.ContentEncoding = ContentEncoding; 如果(数据!= NULL)
{的JavaScriptSerializer串行=新的JavaScriptSerializer();
RESPONSE.WRITE(的String.Format({0}({1});,this.JsonCallback,
serializer.Serialize(数据)));
}}} //为控制器扩展方法允许JSONP。
公共静态类ContollerExtensions
{
公共静态的Json presult JSONP(此控制器控制器,
对象数据)
{
JSON presult结果=新的JSON presult();
result.Data =数据;
result.ExecuteResult(controller.ControllerContext);
返回结果;
}
}
}
至于接收JSON字符串,并将其绑定到一个模型来讲 JsonValueProviderFactory
完成这个工作出ASP.NET MVC 3盒,但没有任何内置的输出JSONP。你可以写一个自定义的的Json presult
:
公共类的Json presult:JsonResult
{
公共覆盖无效的ExecuteReuslt(ControllerContext上下文)
{
如果(上下文== NULL)
{
抛出新的ArgumentNullException(上下文);
}
VAR请求= context.HttpContext.Request;
VAR响应= context.HttpContext.Response;
字符串jsoncallback =(context.RouteData.Values [jsoncallback]作为字符串)?请求[jsoncallback];
如果(!string.IsNullOrEmpty(jsoncallback))
{
如果(string.IsNullOrEmpty(base.ContentType))
{
base.ContentType =应用程序/ x-的javascript
}
RESPONSE.WRITE(的String.Format({0}(jsoncallback));
}
base.ExecuteResult(上下文);
如果(!string.IsNullOrEmpty(jsoncallback))
{
RESPONSE.WRITE());
}
}
}
然后在你的控制器动作:
公众的ActionResult美孚()
{
返回新的Json presult
{
数据= {新名字为prop1 =值1,Prop2 =值2},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
这可能从另一个域与 $食用。的getJSON()
:
$ .getJSON(http://domain.com/home/foo?jsoncallback=?'功能(数据){
警报(data.Prop1);
});
Phil Haack has an excellent blog post on how to use JSON, data binding, and data validation.
Enter the browser's "same origin policy security restriction." and JSONP where you use $.getJSON() to retrieve the content.
Is there a built in MVC 3 way to do this, or do I need to follow the advice of posts like this? Can you post content? I ask because my colleague implemented a JsonPfilterAttribute among other things to make this work. It's obviously preferred to avoid that if something already exists in MVC 3.
Edit:
Summary: everything works with the exception of accessing a POST
variable, i.e., how do I access the POST
variable in the context? (comment marking it in the last section of code)
I elected to use this format to call the server:
$.ajax({
type: "GET",
url: "GetMyDataJSONP",
data: {},
contentType: "application/json; charset=utf-8",
dataType: "jsonp",
jsonpCallback: "randomFunctionName"
});
Which produces this response:
randomFunctionName([{"firstField":"111","secondField":"222"}]);
And all this works very well if I use a GET
. However, I still cannot get this to work as a POST
. Here's the original code posted by Nathan Bridgewater here. This line doesn't find the POST data:
context.HttpContext.Request["callback"];
Either I should be accessing Form
in some way, or the MVC data validators are stripping out the POST variables.
How should context.HttpContext.Request["callback"];
be written to access the POST
variable or is MVC stripping out these values for some reason?
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;
}
}
}
As far as receiving a JSON string and binding it to a model is concerned the JsonValueProviderFactory
does this job out of the box in ASP.NET MVC 3. But there is nothing built-in for outputting JSONP. You could write a custom 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(")");
}
}
}
And then in your controller action:
public ActionResult Foo()
{
return new JsonpResult
{
Data = new { Prop1 = "value1", Prop2 = "value2" },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
which could be consumed from another domain with $.getJSON()
:
$.getJSON('http://domain.com/home/foo?jsoncallback=?', function(data) {
alert(data.Prop1);
});
这篇关于ASP.NET MVC 3 JSONP:是否与JsonValueProviderFactory这项工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!