0

在我正在构建的一个应用程序中,我构建了一个非常灵活的基于属性的系统,用于在我的数据库中描述产品,其中每个产品可以分配给它的属性数量不定,每个属性都有一个“类型”。因此,例如,一种属性类型可能是“类别”,而分配给单个属性的值可能类似于“卡车”。分配给给定产品的属性数量没有限制,并且由于属性和属性类型与产品一起存储在数据库中,因此我的应用程序不会提前知道它们中的任何一个。

给定属性类型的选项的特征之一是它是否“可搜索”。如果属性是可搜索的,我可以使用它的值与其类型名称配对来搜索/过滤我的产品。因此,例如,用户可能希望返回属性类型“类别”等于“卡车”且属性类型“颜色”等于“红色”的所有产品。那里没有什么太独特的地方。

我正在处理的问题是,因为我的系统不提前知道我的属性类型名称是什么,所以我无法轻松地创建一个操作方法来接受像string categoryor这样的可读格式的参数string 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 中并不是特别理想,因为我们最终得到的 URL 类似于?parameters[0].Key=Category&parameters[0].Value=Trucks&parameters[1].Key=Manufacturer&parameters[1].Value=Ford. 这不仅丑陋,而且在实现上也非常有限,因为对 URL 的任何修改都可能破坏整个结果集(如果用户只想通过修改 URL 来搜索第二个参数,他们将不得不删除第一个参数并适当地重新编号整个集合)。

我正在寻找的是一种更好的方法来处理这种情况。理想情况下,我只想有一个查询字符串值?Category=Red并进行相应的过滤,但是我的操作方法不知道是否真的有一个“类别”参数要绑定到。是否有任何介于两者之间的东西可以让我拥有更清晰的查询字符串参数,这些参数不会导致如此糟糕的 URL 结构?

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

4

1 回答 1

2

我更喜欢您的“干净” URI:?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]
             };

您可以按原样使用它,也可以制作自定义模型绑定器。无论哪种情况,代码都不是很多。

于 2010-07-14T17:56:12.000 回答