将routevalue绑定到作为viewmodel一部分的对象的属性

时间:2009-07-02 15:40:08

标签: asp.net-mvc modelbinders

我有以下路线:

            routes.MapRoute(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );

我使用ViewModel:

namespace MvcApplication1.Models
{
    public class ProductViewModel
    {

        public ProductViewModel()
        {
            ProductDetail = new ProductInfo();
        }

        public ProductInfo ProductDetail { get; set; }

    }

    public class ProductInfo
    {
        public string Name { get; set; }
        public int ProductID { get; set; }
    }

}

我需要一种方法将路由的参数id绑定到Model.ProductDetail.ProductID。

/ Products / Display / 2应该导致:

Model.ProductDetail.ProductID == 2

我知道这看起来有点奇怪:如果我的ViewModel只是

那会更简单

公共类ProductViewModel {public int Id {get; set;}}

为了处理partials,我更喜欢使用聚合。我真的不能在主ViewModel类中拥有ID。

我非常害羞,我需要实现自己的ModelBinder,但我没有看到我应该在哪里实现自己的规则。

如何将路径参数“id”映射到属性Model.ProductDetail.ProductID?

编辑:

以下是它的完成方式 -

    public class ProductModelBinder: DefaultModelBinder
{
    protected override void BindProperty(
        ControllerContext controllerContext,
        ModelBindingContext bindingContext, 
        System.ComponentModel.PropertyDescriptor propertyDescriptor
        )    {
            if (bindingContext.ModelType == typeof(ProductViewModel)
            && String.Compare(propertyDescriptor.Name, "ProductDetail", true) == 0)     
            {         
                int id = int.Parse((string)controllerContext.RouteData.Values["id"]);
                ProductViewModel productView = bindingContext.Model as ProductViewModel;
                productView.ProductDetail.ProductID = id;           
                return;       
         }       
        base.BindProperty(controllerContext, bindingContext, propertyDescriptor);    }
}

1 个答案:

答案 0 :(得分:1)

尝试这样的事情(未经测试):

public class CustomModelBinder : DefaultModelBinder
{
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor)
    {
        if (bindingContext.ModelType == typeof(ProductInfo)
            && String.Compare(propertyDescriptor.Name, "ProductID", true) == 0)
        {
            var id = (int)controllerContext.RouteData.Values["id"];

            var productInfo = bindingContext.Model as ProductInfo;

            productInfo.ProductID = id;

            return;
        }

        base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
    }
}