【问题标题】:ASP.NET MVC - get list of objects from query stringASP.NET MVC - 从查询字符串中获取对象列表
【发布时间】:2011-07-18 20:45:06
【问题描述】:

我收到了一个参数列表。如“名称”、“标识”、“类型”。 url中会有很多这样的,像这样:

"Name=blah1,Id=231,Type=blah1;Name=blah2,Id=2221,Type=blah1;Name=blah3,Id=45411,Type=blah3;"

我想知道是否有办法将这些查询参数映射到对象列表。所以,我可以创建一个对象:

MyTestObject {Name;Id;Type} 并且可以在我的控制器中说

Index(IList<MyTestObject> params)

params 将使用查询字符串中的数据填充。

类似于http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx的东西

【问题讨论】:

  • 您是否尝试过实施该链接中的建议?我以前用过它,它满足了我的需求。

标签: asp.net-mvc asp.net-mvc-routing


【解决方案1】:

我实际上遵循了article by Mr. Haack 中的建议,我创建了一个将所有参数作为公共属性的类。然后我有一个视图获取该类型对象的列表。如果查询参数名称遵循某种模式(以索引开头),那么我会得到一个自动填充的对象列表,我根本不需要进行任何手动解析。这对我来说是最简单的解决方案。

例子:

查询参数对象:

public class QueryParams
{
   public string Id,
   public string Name,
   public string Type
}

在控制器方法中:

public ActionResult Index(IList<QueryParams> queryData)

然后我确保查询字符串的格式如下(以索引开头):

http://localhost/myapp/?[0].id=123&[0].Name=blah&[0].Type=Person&[1].Id=345&[1].Name=example&[1] .Type=东西

在我的控制器中,queryData 列表参数将包含两个填充了正确数据的对象。

【讨论】:

  • 这实际上很简单,而且它可以工作!
  • 我希望格式有更好的文档记录——它仍然适用于 .NET5,但这是我发现(经过几天的挖掘)如何传递数组和复杂类型/对象的第一个地方。谢谢!!!
【解决方案2】:

您可以作为值提供者,它将查询字符串中的值填充到单个对象中。如果您不打算创建视图模型,您会这样做。

通过以下方式将 QueryString 转换为 FormCollection:

var GetCollection = new FormCollection( Request.QueryString );

【讨论】:

  • 把它放到你的控制器里。
【解决方案3】:

您可以创建一个自定义模型绑定器,它适用于Request.QueryString 集合,而不是常规的FormCollection

例如:

public class MyTestObjectModelBinder : DefaultModelBinder 
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    {
        var qs = controllerContext.HttpContext.Request.QueryString;                  
        return new MyTestObject
        {
           Name = qs["Name"],
           Id = qs["Id"],
           // etc, etc
        };
    }
}

然后相应地设置您的[HttpGet] 操作:

[HttpGet]
public ActionResult Index([ModelBinder(typeof(MyTestObjectModelBinder))]MyTestObject m) {

}

如果您愿意,您也可以在全球范围内注册它,例如在Application_Start()

ModelBinders.Binders.Add(typeof(MyTestObject), new MyTestObjectModelBinder());

那么你只需要你的动作模型:

[HttpGet]
public ActionResult Index(MyTestObject m) {

}

说了这么多,如果你有这么多参数,你一定要问这些参数是从哪里来的?很可能是另一个页面上的表单。

在这种情况下,这应该是一个[HttpPost] 操作,带有表单集合中的参数,然后常规的 MVC 模型绑定将为您处理上述代码。

【讨论】:

  • +1 我也在考虑自定义模型活页夹,但懒得写自己的答案。
  • @RPM1984 我可以执行以下操作吗?这似乎是一个简单的解决方案。 stackoverflow.com/questions/6739211/…
  • @dev.e.loper - 如果它适合你,当然。然而,这可能会使维护变得困难,因为目前还不清楚绑定是如何工作的,并且您必须维护两个地方(URL 的生成和模型约定)。自定义模型绑定器使其明确,并且是维护绑定的单一位置。但是,任何适合您的方法。
【解决方案4】:

是的,ASP.NET MVC 可以自动将集合绑定到操作参数,但是您需要将参数作为 from 值传递,此外,看起来您将在查询字符串中传递许多参数。看看这个http://weblogs.asp.net/nmarun/archive/2010/03/13/asp-net-mvc-2-model-binding-for-a-collection.aspx

基本上你需要做什么:

1) 创建包含参数的类

public class MyParam 
{
 public int Id {get; set;}
 public string Name {get; set;}

 //do all the rest
}

2) 创建您将传递给视图的模型

public class MyViewModel
{
  IList<MyParam> MyParams {get; set;}
}

3) 在您的 [HttpGet] 操作中创建您的集合并将其传递给您的视图:

[HttpGet]
public virtual ActionResult Index()
{
   MyViewModel model = new MyViewModel();
   model.MyParams = CreateMyParamsCollection();

   return View(model);
}

4) 在视图中迭代您的集合

@model MyViewModel

@{int index = 0;}

@foreach (MyParam detail in Model.MyParams)
{
  @Html.TextBox("MyParams[" + index.ToString() + "].Id", detail.Id)
  @Html.TextBox("MyParams[" + index.ToString() + "].Name", detail.Name)

  index++;
} 

5) 在您的 [HttpPost] 操作中,您可能会收集到您的参数

[HttpPost]
public virtual ActionResult Index(MyViewModel model)

[HttpPost]
public virtual ActionResult Index(IList<MyParam> model)

附言

此外,如果您想在控制器中获取所有表单参数,您可以这样做:

[HttpPost]    
public virtual ActionResult Index(FormCollection form)
【解决方案5】:

在相关说明中,我正在寻找一种方法来枚举 QueryString 名称-值集合,这就是我想出的:

        var qry =HttpContext.Request.QueryString;

        if (qry.HasKeys())
        {
            foreach (var key in qry)
            {
                if(key != null)
                    var str= String.Format("Key:{0}, value:{1} ", key, qry.Get(key.ToString()));
            }
        }

此代码将为您提供 QueryString 中的所有名称及其值。

【讨论】:

  • 不能在 for each 语句中使用 str 变量声明。 str 变量声明应该在 for each 语句之前。
  • 没关系。请参阅以下评论stackoverflow.com/questions/1884906/…
  • 问题是在 Visual Studio 2013 中编译代码时,如果您在 for each 循环中声明变量,则会出现编译器错误。也许有一些配置可以防止这种情况发生,但默认情况下我们会收到编译器错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-30
  • 2016-05-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多