将路由值绑定到属于视图模型一部分的对象的属性

发布于 2024-07-25 14:19:01 字数 2089 浏览 6 评论 0原文

我有以下路线:

            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 只是

public class ProductViewModel{ public int Id {get;set;} , 那就简单多了为了处理部分,

我更喜欢使用聚合。 我确实无法在主 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);    }
}

I have the following route:

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

and I use the 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; }
    }

}

I need a way to bind the parameter id of the route to Model.ProductDetail.ProductID.

/Products/Display/2 should lead to :

Model.ProductDetail.ProductID == 2

I know this looks a bit strange: It would be much simpler if my ViewModel would only be

public class ProductViewModel{ public int Id {get;set;}}

For handling partials I prefer to use aggregation. I realy cant have ID in the main ViewModel class.

I am pretty shure that I need to implement my own ModelBinder, but I dont see where I should implement my own rules.

How can I map the route parameter "id" to the property Model.ProductDetail.ProductID ?

EDIT:

Here is how its done -

    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);    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

送君千里 2024-08-01 14:19:01

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

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);
    }
}

Try something like this (not tested):

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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文