I have a complex entity User:
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; }
}
where Taxi is a parent of User (Taxi has-many Users):
public class Taxi : BaseEntity
{
public virtual string Name { get; set; }
public virtual string ClientIp { get; set; }
}
BaseEntity consists of public virtual int Id { get; private set; }
The problem occurs while trying to edit User
[开发者_JAVA技巧Authorize]
public ActionResult ChangeAccountInfo()
{
var user = UserRepository.GetUser(User.Identity.Name);
return View(user);
}
My 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>
Post changes:
[Authorize]
[HttpPost]
public ActionResult ChangeAccountInfo(User model)
{
if (ModelState.IsValid)
{
UserRepository.UpdateUser(model);
return RedirectToAction("ChangeAccountInfoSuccess", "Account");
}
return View(model);
}
But, the (User model) parameter has User.Id == 0 --> User entity had 5 before edit
User.Login == "my new login" User.Password == "my new password" User.Taxi.Id == 0 --> User.Taxi entity had 3 before edit User.Taxi.Name == "old hidden name" User.Taxi.ClientIp == null --> User entity had 192.168.0.1 before editQ: Is it possible not to mark all the fields of an entity (that should be in my UpdateUser) with tag "hidden" but still have them unchanged in my HttpPost method? e.g. not User.Taxi.ClientIp = null, but User.Taxi.ClientIp = 192.168.0.1
I'm using nhibernate, if it matters.
Not without some heavy lifting. I'm not sure if nhibernate cares that it is the same exact instance or not; you might only have to keep the entity's ID for your form to work.
If the second case is true, all you need to do is create a hidden field in your form to store the id of the model. MVC will do the rest. Just chuck this in your form at the top:
<%= Html.HiddenFor(model => model.Id) %>
You can specify (via a whitelist or a blacklist) what properties can/cannot be edited within the form, if you're concerned about people hacking (and you should be).
The answer suggested by Will is the best matching my issue:
To Edit your entity
- Provide your View with entity identity that you want to edit
- Post your model with identity in hidden field (in my case i can't use model.Id private setter because of nhib mapping settings)
- In httpPost method use GetById(idFromHiddenField) to retrieve your entityFromDatabase
- use UpdateModel(entityFromDatabase) - that will merge old version(entityFromDatabase) and new version of entity
- Then ISession.Update(entityFromDatabase) to persist changes into database
精彩评论