当前位置:编程学习 > JAVA >>

让asp.net mvc的Action支持jQuery直接提交的javascript对象

在某些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;
    }
}
下面是用于支持FormValueProviderFactoryEx的另外几个对象的定义
public sealed class FormValueProviderEx : NameValueCollectionValueProvider
{
    public FormValueProviderEx(ControllerContext controllerContext)
        : this(controllerContext, new UnvalidatedRequestValuesWrapper(controllerContext.HttpContext.Request.Unvalidated()))
    {
 
    }
    internal FormValueProviderEx(ControllerContext controllerContext, IUnvalidatedRequestValues unvalidatedValues)
        : base(controllerContext.HttpContext.Request.Form, unvalidatedValues.Form, CultureInfo.CurrentCulture)
    {
 
    }
 
    public override ValueProviderResult GetValue(string key, bool skipValidation)
    {
        var result = base.GetValue(key, skipValidation);
        if (result == null)
        {
            var subKeys = base.GetKeysFromPrefix(key);
            if (subKeys.Count > 0)
            {
                var firstItem = subKeys.First();
                if (subKeys.Count == 1 && firstItem.Value == key + "[]")
                {
                    return GetValue(firstItem.Value, skipValidation);
                }
                int n;
                if( int.TryParse(firstItem.Key, out n) )
                {
                    var indexList = new List<int>(subKeys.Count);
                    if (subKeys.Keys.All(v =>
             &

补充:Web开发 , ASP.Net ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,