【问题标题】:MVC 3 route for searchMVC 3 搜索路径
【发布时间】:2012-03-05 17:57:49
【问题描述】:

我正在开发一种具有动态数量的复选框和价格范围的搜索。我需要一条映射如下内容的路线:

/Filter/Attributes/Attribute1, Attribute2, Attribute3/Price/1000-2000

这是一个好方法吗?我该如何走这条路线?

【问题讨论】:

    标签: asp.net asp.net-mvc-3 c#-4.0 asp.net-mvc-routing


    【解决方案1】:
    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_StartGlobal.asax注册:

    ModelBinders.Binders.Add(typeof(FilterViewModel), new FilterViewModelBinder());
    

    【讨论】:

    • 我没用过自定义的ModelBinder,能不能发个例子或者链接说明一下如何使用,会很有用的! :)
    猜你喜欢
    • 2019-09-07
    • 2011-07-31
    • 2012-06-07
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-26
    • 2011-01-20
    相关资源
    最近更新 更多