ASP .NET MVC实战:jQuery提交对象
在某些ajax应用中,我们可能会用到如下的场景:$.post('/Test/PostTest', { values: [1, 2, 3, 4] }, function(result){
//TODO:
}, 'json' );
我们希望提交一个数组给服务器。
于是我们创建了一个如下的Controller,来负责处理上面的ajax请求:public class TestController : Controller
{
[HttpPost]
public JsonResult PostTest( int[] values )
{
//TODO:
return Json( new { success = true });
}
}
可是当我们充满期待的去测试我们刚才的代码时,却发现了一个问题。
▲
值并没有被正确的传过来。
于是我们打开了浏览器的开发人员工具,来看看到底jQuery提交了什么内容给我们的服务器。
▲
我们发现,表单名称被设置成为了 values[],而不是values。莫非是是mvc不能将values[]看成一个数组并自动转化么?
于是我们打开ILSpy,找到了System.Web.Mvc.FormValueProviderFactory的源代码,并将它复制出来,作了一些扩展,以支持我们想要的功能。public sealed class FormValueProviderFactoryEx
: ValueProviderFactory
{
private readonly UnvalidatedRequestValuesAccessor _unvalidatedValuesAccessor;
public FormValueProviderFactoryEx()
: this(null)
{
}
internal FormValueProviderFactoryEx(UnvalidatedRequestValuesAccessor unvalidatedValuesAccessor)
{
if (unvalidatedValuesAccessor == null)
{
unvalidatedValuesAccessor = ((ControllerContext cc) => new UnvalidatedRequestValuesWrapper(cc.HttpContext.Request.Unvalidated()));
}
this._unvalidatedValuesAccessor = unvalidatedValuesAccessor;
}
public override IValueProvider GetValueProvider(ControllerContext controllerContext)
{
if (controllerContext == null)
{
throw new ArgumentNullException("controllerContext");
}
return new FormValueProviderEx(controllerContext, this._unvalidatedValuesAccessor(controllerContext));
}
}
下面这几个是原来的FormValueProviderFactory用到的,但在System.Web.Mvc.dll中被声明为internal,所以不得已复制了出来。internal interface IUnvalidatedRequestValues
{
NameValueCollection Form { get; }
NameValueCollection QueryString {get;}
string this[string key]{ get; }
}
internal delegate IUnvalidatedRequestValues UnvalidatedRequestValuesAccessor(ControllerContext controllerContext);
internal sealed class UnvalidatedRequestValuesWrapper : IUnvalidatedRequestValues
{
private readonly UnvalidatedRequestValues _unvalidatedValues;
public NameValueCollection Form
{
get
{
return this._unvalidatedValues.Form;
}
}
public NameValueCollection QueryString
{
get
{
return this._unvalidatedValues.QueryString;
}
}public string this[string key]
{
get
{
return this._unvalidatedValues[key];
}
}
public UnvalidatedRequestValuesWrapper(UnvalidatedRequestValues unvalidatedValues)
{
this._unvalidatedValues = unvalidatedValues;