Nhibernate Net MVC 2是否可以在HttpPost方法中获得与HttpGet中传递的相同的模型实例(稍作更改)

Nhibernate Net MVC 2是否可以在HttpPost方法中获得与HttpGet中传递的相同的模型实例(稍作更改),nhibernate,asp.net-mvc-2,model-binding,Nhibernate,Asp.net Mvc 2,Model Binding,我有一个复杂的实体用户: public class User : BaseEntity { public virtual Taxi Taxi { get; set; } --> That is why i call it "complex" public virtual string Login { get; set; } public virtual string Password { get; set; }

我有一个复杂的实体用户:

    public class User : BaseEntity
    {        
    public virtual Taxi Taxi { get; set; }  --> That is why i call it "complex"
    public virtual string Login { get; set; }           
    public virtual string Password { get; set; }  
    }
如果出租车是用户的家长(出租车有许多用户):

BaseEntity由公共虚拟整数Id{get;private set;}组成

尝试编辑用户时出现问题

    [Authorize]  
    public ActionResult ChangeAccountInfo()
    {
        var user = UserRepository.GetUser(User.Identity.Name);
        return View(user); 
    }
我的ChangeAccountInfo.aspx

        <fieldset>
        <legend>Fields</legend>
        <%  %>
        <div class="editor-label">
            <%: Html.LabelFor(model => model.Login) %>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.Login) %>
            <%: Html.ValidationMessageFor(model => model.Login) %>      
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Password) %>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.Password) %>
            <%: Html.ValidationMessageFor(model => model.Password) %>
        </div>  

         <div class="editor-field">
            <%: Html.HiddenFor(model => model.Taxi.Name)%>               
        </div>     

        <p>
            <input type="submit" value="Save" />
        </p>
       </fieldset>
但是,(用户模型)参数 User.Id==0-->用户实体在编辑之前有5个 User.Login==“我的新登录”
User.Password==“我的新密码”
User.Taxi.Id==0-->User.Taxi实体在编辑之前有3个 User.Taxi.Name==“旧隐藏名称”
User.Taxi.ClientIp==null-->用户实体在编辑之前拥有192.168.0.1

Q: 是否可以不使用标记“hidden”标记实体(应该在我的UpdateUser中)的所有字段,但在我的HttpPost方法中仍然保持不变? e、 g.不是User.Taxi.ClientIp=null,而是User.Taxi.ClientIp=192.168.0.1


如果有必要的话,我正在使用nhibernate。

不是没有一些重物。我不确定nhibernate是否关心它是否是相同的实例;您可能只需要保留实体的ID即可使表单正常工作

如果第二种情况为真,则只需在表单中创建一个隐藏字段来存储模型的id。MVC将完成剩下的工作。把这个放在你的表格顶部:

<%= Html.HiddenFor(model => model.Id) %>
model.Id)%%>

您可以指定(通过白名单或黑名单)哪些属性可以/不能在表单中编辑,如果您担心人员黑客攻击(您应该这样做)

威尔建议的答案最符合我的问题:
编辑实体的步骤
-为视图提供要编辑的实体标识
-在隐藏字段中发布带有标识的模型(在我的情况下,由于nhib映射设置,我无法使用model.Id private setter)
-在httpPost方法中,使用GetById(idFromHiddenField)从数据库检索entityFromDatabase
-使用UpdateModel(entityFromDatabase)-这将合并实体的旧版本(entityFromDatabase)和新版本

-然后ISession.Update(entityFromDatabase)将更改持久化到数据库中

我认为有某种方法可以在编辑后获得实体实例,只更改很少的可编辑字段,而所有其他只读字段保留其旧值。我在asp mvc和nhibernate中都是新手,所以我仍然需要检查nhibernate只指定User.Taxi.Id是否足以在用户和Taxi之间拥有正确的引用,并且不会导致无效的Taxi更新。@jj您必须意识到asp.NET mvc(以及一般的web)是无状态的。除了少数例外,在从客户端到服务器的调用之间,一切都会消失。因此,除非您使用某种存储机制在调用之间“保留”对模型实例的引用(不管调用的时间有多长),否则一旦控制器方法退出,系统将立即处理并收集该引用。廉价且肮脏的方法是将用户存储在会话中。更好的解决方案是我提供的,imho。还有其他的方法,这也取决于你的需求……是的,我在http会话中不需要用户对象这么长时间。现在我的Id属性对我的所有实体都是私有的(使用nhib的应用程序的通用解决方案),所以Html.HiddenFor(model=>model.Id)为Id返回0。即使将其公开也不能解决问题,它仍然不会更新用户,因为User.Taxi中的notnull字段未填充。我现在看到的方法是在httpPost方法中通过id获取oldUser,使用newUser的received(posted)实例手动更新它,然后使用更改保存oldUser。我理解你对网络的解释,谢谢,现在问题已经解决了nhibernate@jjj对不起,我无法具体帮助您进行nhib。您可以尝试从存储库中获取用户的当前版本,然后使用try/UpdateModel方法更新用户。@Paco-这很重要,因为???MVC绝对不需要视图模型(也不应该)。@Charles Boyung-MVC模式不需要单独的域模型和视图模型。在像Ruby这样使用duck类型的语言中,您可以很容易地使用一个模型。在.Net中,没有duck类型。您可以使用一个模型,但当视图和控制器变得比标准场景更复杂时,将很难在一个域实体中容纳所有逻辑、数据和显示数据。在.net中创建专用类的工作量可能更少。在MVC场景中,duck类型和静态编译方法各有优缺点。
    [Authorize]
    [HttpPost]
    public ActionResult ChangeAccountInfo(User model)
    {
        if (ModelState.IsValid)
        {
            UserRepository.UpdateUser(model); 

            return RedirectToAction("ChangeAccountInfoSuccess", "Account");
        }

        return View(model);
    }
<%= Html.HiddenFor(model => model.Id) %>