【问题标题】:Is it possible to get Dictionary from query string?是否可以从查询字符串中获取字典?
【发布时间】:2014-03-28 08:39:20
【问题描述】:

我的控制器方法如下所示:

public ActionResult SomeMethod(Dictionary<int, string> model)
{

}

是否可以调用此方法并仅使用查询字符串填充“模型”?我的意思是,输入如下内容:

ControllerName/SomeMethod?model.0=someText&model.1=someOtherText

在我们的浏览器地址栏中。有可能吗?

编辑:

看来我的问题被误解了——我想绑定查询字符串,以便自动填充 Dictionary 方法参数。换句话说 - 我不想在我的方法中手动创建字典,但是有一些自动的 .NET 活页夹来完成它,所以我可以像这样立即访问它:

public ActionResult SomeMethod(Dictionary<int, string> model)
{
    var a = model[SomeKey];
}

有没有足够聪明的自动活页夹?

【问题讨论】:

  • @max 也没有真正提高可读性。
  • @CodeCaster 它比以前更好,因为它看起来不像是问题的一部分,而更像是其他人如何实现它的示例。你现在做的更好。
  • @Portekoi:请看我的编辑。

标签: c# asp.net-mvc-4 query-string


【解决方案1】:

在 ASP.NET Core 中,您可以使用以下语法(无需自定义绑定器):

?dictionaryVariableName[KEY]=VALUE

假设你有这个作为你的方法:

public ActionResult SomeMethod([FromQuery] Dictionary<int, string> model)

然后调用如下网址:

?model[0]=firstString&model[1]=secondString

然后您的字典将被自动填充。有价值观:

(0, "firstString")
(1, "secondString")

【讨论】:

  • route 属性对于这样的事情会是什么样子?
  • 如果您有其他查询参数,请添加[FromQuery(Name = "model")]属性,以确保在没有传递model[key]=value等查询参数的情况下,模型属性不会捕获其他查询参数。
【解决方案2】:

对于 .NET Core 2.1,您可以非常轻松地做到这一点。

public class SomeController : ControllerBase
{
    public IActionResult Method([FromQuery]IDictionary<int, string> query)
    {
        // Do something
    }
}

还有网址

/Some/Method?1=value1&amp;2=value2&amp;3=value3

它将绑定到字典。您甚至不必使用参数名称查询。

【讨论】:

  • 当你想要两个参数,其中一个是一个简单的布尔值或者不应该在那个字典里的东西时怎么办?
  • 你必须将它绑定到一个变量,就像在 bfactos 的答案中一样。 name[key]=value
【解决方案3】:

尝试自定义模型绑定器

      public class QueryStringToDictionaryBinder: IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var collection = controllerContext.HttpContext.Request.QueryString;
        var modelKeys =
            collection.AllKeys.Where(
                m => m.StartsWith(bindingContext.ModelName));
        var dictionary = new Dictionary<int, string>();

        foreach (string key in modelKeys)
        {
            var splits = key.Split(new[]{'.'}, StringSplitOptions.RemoveEmptyEntries);
            int nummericKey = -1;
            if(splits.Count() > 1)
            {
                var tempKey = splits[1]; 
                if(int.TryParse(tempKey, out nummericKey))
                {
                    dictionary.Add(nummericKey, collection[key]);    
                }   
            }                 
        }

        return dictionary;
    }
}

在控制器动作中在模型上使用它

     public ActionResult SomeMethod(
        [ModelBinder(typeof(QueryStringToDictionaryBinder))]
        Dictionary<int, string> model)
    {

        //return Content("Test");
    }

【讨论】:

    【解决方案4】:

    更具体的mvc模型绑定是将查询字符串构造为

    /somemethod?model[0].Key=1&model[0].Value=One&model[1].Key=2&model[1].Value=Two

    自定义 Binder 只需遵循 DefaultModelBinder

       public class QueryStringToDictionary<TKey, TValue> : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var modelBindingContext = new ModelBindingContext
            {
    
                ModelName = bindingContext.ModelName,
                ModelMetadata = new ModelMetadata(new EmptyModelMetadataProvider(), null, 
                    null, typeof(Dictionary<TKey, TValue>), bindingContext.ModelName),
                ValueProvider = new QueryStringValueProvider(controllerContext)
            };
    
            var temp = new DefaultModelBinder().BindModel(controllerContext, modelBindingContext);
    
            return temp;
        }
    }
    

    在模型中应用自定义模型绑定器

         public ActionResult SomeMethod(
            [ModelBinder(typeof(QueryStringToDictionary<int, string>))] Dictionary<int, string> model)
        {
           // var a = model[SomeKey];
            return Content("Test");
        }
    

    【讨论】:

      猜你喜欢
      • 2017-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-06
      • 2020-11-09
      • 2013-05-16
      • 1970-01-01
      • 2011-05-14
      相关资源
      最近更新 更多