受保护的变量和模型绑定

时间:2017-10-09 15:36:36

标签: c# asp.net-mvc nhibernate

请参阅以下型号:

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受到保护。

2 个答案:

答案 0 :(得分:2)

有几种解决方法,包括实现公共的子类,其setter将值应用于受保护的id字段。

然而这些是绷带。通常会遇到这些问题,因为人们看待模型的方式不同。它是一个可重用的数据传输对象,或者它不是。

在不存在的世界中,你必须将业务对象变为可绑定的模型,并始终遇到这些奇怪的问题。

在它们所处的世界中,它们是根据数据需求进行定制的,并通过类似自动化程序的方式映射到业务对象中。更重要的是,通过制作适合此请求的模型,可以防止对意外暴露参数的攻击。<​​/ p>

如果临时业务对象具有可改变您行为的公共属性,则可以通过使用发布请求发回其他参数来利用它们。

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

答案 1 :(得分:0)

正如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帖子似乎做了基础知识。这会得到你需要的吗?