2010-07-14 63 views
0

在我构建的一个应用程序中,我构建了一个非常灵活的基于属性的系统,用于描述我的数据库中的产品,其中每个产品可以具有不确定数量的属性分配给它,每个属性只有一个“类型”。因此,例如,一种属性类型可能是“类别”,并且分配给单个属性的值可能类似于“卡车”。对分配给给定产品的属性数量没有限制,并且因为属性和属性类型与产品一起存储在数据库中,所以我的应用程序不会提前知道它们中的任何一个。ASP.NET MVC - 清理复杂模型绑定场景中的URL

给定属性类型的选项之一是它是否是“可搜索的”。如果某个属性是可搜索的,我可以使用与其类型名称配对的值来搜索/过滤我的产品。因此,例如,用户可能想要返回具有属性类型“类别”等于“卡车”和属性类型“颜色”等于“红色”的所有产品。这里没有什么特别的。

我处理麻烦的是,因为我的系统不提前知道什么时候我的属性的类型名称,我不能很容易地创建一个操作方法接受像string categorystring color可读的格式参数。作为一个解决方案,我使用了DefaultModelBinder对绑定到字典的支持。通过这种方法,我只需要在正确的结构中格式化我的字段名称,然后我的操作方法就可以接受IDictionary<string,string> parameters。这一切运行良好,但当用户通过单个参数执行基于链接的过滤器时,它会产生一些非常糟糕的URL,即“查看更多类别卡车中的产品”。随着DefaultModelBinder结合到词典需要您的字段命名方式如下所示:

<input type="hidden" name="parameters[0].Key" value="Category" /> 
    <select name="parameters[0].Value"> 
    <option value="Trucks">Trucks</option> 
    <option value="Compacts">Compacts</option> 
    <option value="SUVs">SUVs</option> 
</select> 
<input type="hidden" name="parameters[1].Key" value="Manufacturer" /> 
<select name="parameters[1].Value"> 
    <option value="Ford">Ford</option> 
    <option value="Toyota">Toyota</option> 
    <option value="Honda">Honda</option> 
</select> 

这不仅是令人难以置信的繁琐,但也有些沮丧由于每个键/值必须包含一个序号索引在字段名称中。虽然这对于POST表单来说是可以接受的,但它在GET URL中并不是特别理想,因为我们最终得到类似于?parameters[0].Key=Category&parameters[0].Value=Trucks&parameters[1].Key=Manufacturer&parameters[1].Value=Ford的URLS。这不仅丑陋,它的实现非常有限,因为对URL的任何修改都可能破坏整个结果集(如果用户想通过修改URL来搜索第二个参数,则必须删除第一个参数并适当重新编号整个集合)。

我在寻找的是处理这种情况的更好方法。理想情况下,我只想简单地查询字符串值?Category=Red并相应地进行过滤,但是然后我的操作方法不知道是否实际上存在要绑定的“类别”参数。有没有什么可以让我有更清晰的查询字符串参数,不会造成如此糟糕的URL结构?

我在考虑建立自己的自定义ModelBinder,但是如果还有其他方法,我想避免这种情况。

回答

2

我更喜欢你的“干净的”URIs:?Category=Red。所以让我们从那里开始,看看它是如何工作的。

您可以在运行时加载所有类别,对吧?关闭我的头顶:

IEnumerable<string> allCategories = Categories.GetAll(); 
var usedCategories = Request.QueryString.AllKeys.Intersect(allCategories); 
var search = from c in usedCategories 
      select new 
      { 
       Key = c, 
       Value = Request.QueryString[c] 
      }; 

您可以按原样使用,或制作自定义模型活页夹。无论哪种情况,这都不是很多代码。

+0

不错。我非常喜欢这个解决方案。当我看到它是如何运作的时候,我会报告回来。 – 2010-07-14 18:27:21

+0

布拉沃先生。真正做到。 – 2010-07-14 20:50:58

+0

不错而优雅的解决方案。谢谢。 – 2012-10-31 10:20:24