【问题标题】:Protected Variables and model binding受保护的变量和模型绑定
【发布时间】:2017-10-10 00:32:39
【问题描述】:

请查看以下型号:

public class Apple //: Fruit
    {
        public string Description { get; set; }
        public int Id { get; protected  set; }
    }

    public class AppleModel
    {
        public int Id { get; set; }
        public string Description { get; set; }
    }

和下面的控制器:

 [HttpPost]
            public ActionResult Index(Apple apple)
            {
                return View();
            }

            [HttpGet]
            public ActionResult Index()
            {
                var AppleModel = new AppleModel();
                AppleModel.Id = 1;
                AppleModel.Description = "Apple";
                var Apple = AutoMapper.Mapper.Map<Apple>(AppleModel);
                return View("View1",Apple);
            }

以及下面的视图:

    @model PreQualification.Web.Controllers.Apple

    @{
        ViewBag.Title = "View1";
    }

    <h2>View1</h2>


    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()

        <div class="form-horizontal">
            <h4>AppleModel</h4>
            <hr />
            @Html.ValidationSummary(true)


            <div class="form-group">
                @Html.LabelFor(model => model.Id)
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Id)
                    @Html.ValidationMessageFor(model => model.Id)
                </div>
            </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.Description, new { @class = "control-label col-md-2" })
                    <div class="col-md-10">
                        @Html.EditorFor(model => model.Description)
                        @Html.ValidationMessageFor(model => model.Description)
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-offset-2 col-md-10">
                        <input type="submit" value="Save" class="btn btn-default" />
                    </div>
                </div>
            </div>
    }

    <div>
        @Html.ActionLink("Back to List", "Index")
    </div>

    @section Scripts {
        @Scripts.Render("~/bundles/jqueryval")
    }

Apple.Id 在 HttpPost 方法中为 0,因为它是模型中的受保护变量。反正有这个吗?

我问的原因是因为我试图将其用作模型:https://github.com/nhibernate/NHibernate.AspNet.Identity/tree/master/source/NHibernate.AspNet.Identity 并且包含在超类中的 id 是受保护的。

【问题讨论】:

  • @David,我更新了我的帖子。对不起。
  • 你为什么不在 Post 方法中使用AppleModel

标签: c# asp.net-mvc nhibernate


【解决方案1】:

有几种方法可以解决这个问题,包括实现 public 的子类,其 setter 将值应用于受保护的 id 字段。

不过,这些都是创可贴。通常,由于人们对模型的看法不同,会遇到这些问题。它要么是可重用的数据传输对象,要么不是。

在没有它的世界里,您必须将业务对象硬塞到可绑定的模型中,并且总是遇到这些奇怪的问题。

在它们所处的世界中,它们是为满足数据需求而定制的,并通过自动映射器之类的东西映射到业务对象中。更重要的是,通过制作适合此请求的模型,您可以防止对意外暴露的参数的攻击。

如果临时业务对象具有改变您行为的公共属性,则可以通过将附加参数与发布请求一起发送回来利用它们。

我知道这并不能具体回答您的问题,但遵循模型不是 DTO 的路径可能也不是正确的答案。

【讨论】:

    【解决方案2】:

    正如 peewee_RotA 所阐述的,最好将用于视图的模型与将实际执行操作或用于直接执行操作的域模型之间的概念差异区分开来。为此,您需要一个视图模型,例如Apple

    public class Apple
    {
        public string Description { get; set; }
        public int Id { get; set; }
    }
    

    在您的发布操作中,您将拥有;

    [HttpPost]
    public ActionResult Index(Apple apple)
    {
        // translate your view model to your domain model
        AppleModel model = new AppleModel(apple.Id, apple.Description);
        model.DoStuff();
    }
    

    但是,就 NHiberhate 而言,使用视图模型的 ID 实例化所需的对象并不容易,我认为这是您问题的症结所在。您正在尝试将域模型用作视图模型,并且域模型被锁定......合法。它的工作是控制IdentityUser 之类的实例化方式,因为它们是由关联的工厂类生成的,而不是 MVC 的模型绑定器。

    为此,让您的视图模型尽可能简单,并利用 NHibernate 的工厂类通过查找 ID 创建必要的 Identity 对象。 This 链接可能有助于了解如何查找Apple.Id 传入的用户 ID。

    编辑

    我对在 NHibernate 中查找实体进行了更多挖掘,following 帖子似乎做了基础知识。这能满足您的需要吗?

    【讨论】:

      猜你喜欢
      • 2018-07-16
      • 2016-03-08
      • 2011-08-02
      • 2012-09-05
      • 1970-01-01
      • 2016-12-17
      • 1970-01-01
      • 2015-08-11
      • 2010-09-30
      相关资源
      最近更新 更多