我们将MVC 4与Entity Framework结合使用。
我有一个持久的Entity基类,这个类定义所有实体都有一个生成的代码GUID Id
:
public abstract class Entity
{
public Guid Id {get; set;}
;...
}
以下具体课程:
public class Person : Entity
{
public List<Position> Positions{get;set;}
;...
}
public class Position : Entity
{
;...
public Guid Person{get; set;}
public Guid PersonId{get; set;} //recently added because of other EF issues :-(
}
在Position的视图中,我们尝试了几件事,但MVC非常坚持不懈地尝试 将“Id”替换为“PersonId”:
@Html.HiddenFor(x => x.Id)
@Html.HiddenFor(x => x.PersonId)
如果我们只有一个Id隐藏字段,则在渲染视图时会被PersonId覆盖 如果我们将它设为“PositionId”,它将被保留并返回FormValue Collection (Request [“PositionId”]产生正确的值)但MVC ModelBinder再次搞砸了事情:
public ActionResult Edit (Postion model)
{
// model.Id = Guid.Parse(Request["PositionId"]);
...
bool isFoiledAganin = modelId.Equals(model.PersonId); // true
}
只有取消注释model.Id
作业才能解决问题。
我的猜测是,当它在类中找到带有“id”的内容时,ModelBinder就会失去它,而不考虑继承的字段。 有没有办法让她直接? < / p>
答案 0 :(得分:3)
到目前为止,所给出的答案都没有解释正在发生的事情或解决问题。现在我们实施黑客攻击: 在视图中,我们将Id放在隐藏字段中,我们明确地将其命名为Id:
@Html.Hidden("PositionId", Model.Id);
这确保View中的正确ID放在HTML中,并且它将在FormValueCollection中返回。
控制器方法的第一个操作是检索该值并将其恢复到模型:
model.Id = Guid.Parse(Request["PositionId"]);
很糟糕,但它击败了替代品
答案 1 :(得分:1)
我可能不理解这个问题,但为什么不使用强类型变体HiddenFor
:
@Html.HiddenFor(model => model.Id);
@Html.HiddenFor(model => model.Person.Id);
您可以像这样获取控制器中的值:
public ActionResult Edit (Postion model)
{
Guid positionId = model.Id;
Guid personId = model.Person.Id;
}
<强>更新强>
您不应在视图中使用域(实体)模型,而是创建ViewModels:
public class PositionModel
{
public Guid Id { get; set; }
public Guid PersonId { get; set; }
// ...
}
然后在你的控制器中:
public ActionResult Edit (int positionId)
{
// Get position from db.
Position position = db.Positions.Find(positionId);
// Map it to a ViewModel.
PositionModel positionModel = new PositionModel
{
Id = position.Id,
PersonId position.Person.Id
};
return View(positionModel);
}
[HttpPost]
public ActionResult Edit (Postion model)
{
Guid positionId = model.Id;
Guid personId = model.PersonId;
}
您的观点将如下所示:
@model PositionModel;
@Html.HiddenFor(model => model.Id);
@Html.HiddenFor(model => model.PersonId);
答案 2 :(得分:0)
这是因为您给出了名称PersonID而不是id。所以改名。
@Html.Hidden("PersonId", Model.Person.Id)
至 @Html.Hidden("Id", Model.Person.Id)
答案 3 :(得分:0)
使用此
@Html.HiddenFor(model => model.Id);
@Html.HiddenFor(model => model.Person.Id);
希望这有帮助。