ASP.Net MVC请求ViewModel无法解析

时间:2013-12-29 17:05:53

标签: c# asp.net asp.net-mvc asp.net-mvc-4 asp.net-mvc-viewmodel

我有这样的请求:

filter[logic]:and
filter[filters][0][value]:a
filter[filters][0][operator]:startswith
filter[filters][0][field]:result
filter[filters][0][ignoreCase]:true

我需要在控制器上接收它,但我不确切知道如何。我试过这个视图模型:

{
    public class SearchFilterViewModel
    {
        public string logic { get; set; }
        public List<SearchFilterFiltersViewModel> filters { get; set; }
    }

    public class SearchFilterFiltersViewModel
    {
        public string value { get; set; }
        //public string operator { get; set; }
        public string field { get; set; }
        public bool ignoreCase { get; set; }
    }
}

但是Controller收到它全部为null。 operator属性被注释,因为operator是一个保留关键字,我不知道如何让Asp.Net使用它。而且我不知道这是否是问题的原因。

请注意,我无法更改请求正文模式,因为它来自this Kendo Widget。

这是我的控制器(测试版):

public ActionResult Text(SearchFilterViewModel filter)
{
    return Json("", JsonRequestBehavior.AllowGet);
}

1 个答案:

答案 0 :(得分:1)

这是工作解决方案

型号:

public class SearchFilterViewModel
{
    public string logic { get; set; }
    public List<SearchFilterFiltersViewModel> filter { get; set; }
}

public class SearchFilterFiltersViewModel
{
    public string value { get; set; }
    public string oper { get; set; }
    public string field { get; set; }
    public bool ignoreCase { get; set; }
}

然后你可以编写自定义IValueProvider,你可以覆盖通常的解析机制,如下所示:

public class KendoValueProvider : NameValueCollectionValueProvider
{
    public KendoValueProvider(NameValueCollection originalCollection)
        : base(UpdateCollection(originalCollection), CultureInfo.InvariantCulture)
    {
    }

    private static NameValueCollection UpdateCollection(NameValueCollection collection)
    {
        NameValueCollection result = new NameValueCollection();

        foreach (string key in collection.Keys)
        {
            // ignore all other request
            if (!key.StartsWith("filter"))
                return null;

            var newKey = key
                .Replace("[filters]", string.Empty)
                .Replace("filter[logic]", "logic")
                .Replace("[value]", ".value")
                .Replace("[operator]", ".oper")
                .Replace("[field]", ".field")
                .Replace("[ignoreCase]", ".ignoreCase");

            var value = collection[key];

            result.Add(newKey, value);
        }
        return result;
    }
}

然后你需要编写ValueProviderFactory来注册这个ValueProvider,如下所示:

public class KendoValueProviderFactory : ValueProviderFactory
{
    public override IValueProvider GetValueProvider(ControllerContext controllerContext)
    {
        return new KendoValueProvider(controllerContext.HttpContext.Request.QueryString);
    }
}

最后一步是在Global.asax文件中注册

ValueProviderFactories.Factories.Add(new KendoValueProviderFactory());

示例动作

[HttpGet]
public ActionResult Index(SearchFilterViewModel model)
{
      return Json(model, JsonRequestBehavior.AllowGet);
}