ASP .NET MVC实战:jQuery提交对象

2013 年 8 月 9 日4090

  在某些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 });

  }

  }

  可是当我们充满期待的去测试我们刚才的代码时,却发现了一个问题。

ASP.NETMVC实战:jQuery提交对象

  ▲

  值并没有被正确的传过来。

  于是我们打开了浏览器的开发人员工具,来看看到底jQuery提交了什么内容给我们的服务器。

ASP.NETMVC实战: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;

0 0