我正在开发一个具有动态数量的复选框和价格范围的搜索。我需要一个映射这样的路线:
/ Filter / Attributes / Attribute1,Attribute2,Attribute3 / Price / 1000-2000
这是一个很好的方法吗?我该怎么办?
答案 0 :(得分:4)
routes.MapRoute(
"FilterRoute",
"filter/attributes/{attributes}/price/{pricerange}",
new { controller = "Filter", action = "Index" }
);
并在您的索引操作中:
public class FilterController: Controller
{
public ActionResult Index(FilterViewModel model)
{
...
}
}
其中FilterViewModel
:
public class FilterViewModel
{
public string Attributes { get; set; }
public string PriceRange { get; set; }
}
如果您希望FilterViewModel看起来像这样:
public class FilterViewModel
{
public string[] Attributes { get; set; }
public decimal? StartPrice { get; set; }
public decimal? EndPrice { get; set; }
}
你可以为这个视图模型编写一个自定义模型绑定器,它将解析各种路径令牌。
如果你需要一个例子,请告诉我。
更新:
根据要求,这是一个样本模型绑定器,可用于将路由值解析为相应的视图模型属性:
public class FilterViewModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var model = new FilterViewModel();
var attributes = bindingContext.ValueProvider.GetValue("attributes");
var priceRange = bindingContext.ValueProvider.GetValue("pricerange");
if (attributes != null && !string.IsNullOrEmpty(attributes.AttemptedValue))
{
model.Attributes = (attributes.AttemptedValue).Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries);
}
if (priceRange != null && !string.IsNullOrEmpty(priceRange.AttemptedValue))
{
var tokens = priceRange.AttemptedValue.Split('-');
if (tokens.Length > 0)
{
model.StartPrice = GetPrice(tokens[0], bindingContext);
}
if (tokens.Length > 1)
{
model.EndPrice = GetPrice(tokens[1], bindingContext);
}
}
return model;
}
private decimal? GetPrice(string value, ModelBindingContext bindingContext)
{
if (string.IsNullOrEmpty(value))
{
return null;
}
decimal price;
if (decimal.TryParse(value, out price))
{
return price;
}
bindingContext.ModelState.AddModelError("pricerange", string.Format("{0} is an invalid price", value));
return null;
}
}
将在Application_Start
中的Global.asax
中注册:
ModelBinders.Binders.Add(typeof(FilterViewModel), new FilterViewModelBinder());