能否从查询字符串中获取字典?

16

我的控制器方法长这样:

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

}

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

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

在我们的浏览器地址栏中是否可以实现?

编辑:

看起来我的问题被误解了 - 我想绑定查询字符串,以便字典方法参数自动填充。换句话说 - 我不想手动在我的方法内创建字典,而是让一些自动的.NET绑定程序为我完成,这样我就可以立即像这样访问它:

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

有没有一种自动粘合剂,足够智能,可以做到这一点?


请查看此链接:https://dev59.com/NXE95IYBdhLWcg3wSb_P - Portekoi
@max,这并没有真正提高可读性。 - CodeCaster
@CodeCaster,这次比之前好多了,因为它看起来不像是问题的一部分,而更像是别人如何实现它的示例。你现在做的更好了。 - Max
请查看我的编辑。 - user2384366
4个回答

21
在ASP.NET Core中,您可以使用以下语法(无需自定义绑定器):
?dictionaryVariableName[KEY]=VALUE
假设你有以下方法:

Assuming you had this as your method:


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

然后调用以下URL:

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

您的字典将会自动填充,包含以下数值:

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

像这样的东西,route属性会是什么样子? - Storm Muller
如果您有其他查询参数,请添加[FromQuery(Name = "model")]属性,以确保如果没有传递类似于model[key]=value的查询参数,则模型属性不会捕获其他查询参数。 - dinesh ygv

12

对于 .NET Core 2.1,你可以很容易地做到这一点。

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

而且这个 URL

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

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


5
如果您需要两个参数,其中一个是简单的布尔值或不应该在该字典中的其他内容,该怎么办? - djsoteric
1
你需要像bfactos的回答一样将其绑定到一个变量上。name[key]=value - Todd Skelton

1
尝试使用自定义模型绑定器。
      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");
    }

1
更具体地说,针对mvc模型绑定,构建查询字符串的方式是:

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

自定义绑定器只需遵循默认模型绑定器即可。

   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");
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接