asp.net mvc 脚手架和 GUID 作为主键
我有一个具有以下结构的表
GUID uniqueidentifier with default value newid(), and set as primary key
ID int
Description varchar(max)
我使用 Visual Studio 创建了一个实体模型,并生成了用于编辑/删除等的视图(MVC 脚手架)
问题在于“编辑”,当我单击该链接时,会显示适当的表单数据正确,但“保存”按钮根本不起作用。请注意,其他链接(删除、创建、详细信息)工作正常。
因此,当我单击“编辑”链接时,网址为
http://localhost:10871/admin/Edit/e7d0c5ee-7782-411f-920e-7b0d93c924e1
表单显示正确,但保存按钮不起作用,没有网络活动发生。使用 uniqueidentifers 作为主键有什么特别之处吗?
谢谢
---代码---
Edit.cshtml
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Domain</legend>
@Html.HiddenFor(model => model.GUID)
@Html.HiddenFor(model => model.ID)
<div class="editor-label">
@Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Description)
@Html.ValidationMessageFor(model => model.Description)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
--AdminController.cs--
// GET: /Admin/Edit/5
public ActionResult Edit(Guid id)
{
Domain domain = db.Domains.Single(d => d.GUID == id);
return View(domain);
}
//
// POST: /Admin/Edit/5
[HttpPost]
public ActionResult Edit(Domain domain)
{
if (ModelState.IsValid)
{
db.Domains.Attach(domain);
db.ObjectStateManager.ChangeObjectState(domain, EntityState.Modified);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(domain);
}
Edit2 为了回应 ZippyV 的评论,
<div class="editor-label">
@Html.LabelFor(model => model.ID)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ID)
@Html.ValidationMessageFor(model => model.ID)
</div>
令我惊讶(或无知)的是,我在 Edit.cshtml 中添加了以下代码 - 显示的是 GUID 而不是 ID
除此之外 - 当我在该字段中输入值(1,2 或任何整数)时,我仍然收到消息“字段 ID 必须是数字”。
I have a table with the following structure
GUID uniqueidentifier with default value newid(), and set as primary key
ID int
Description varchar(max)
I created an Entity Model using visual studio, and generated the views for editing/deleting etc (mvc scaffolding)
The problem is with "Editing", when I click that link, the appropriate form is showed with the correct data, but the "save" button doesn't work at all. Please note that other links (delete,create,details) work perfectly..
So, when I click the "Edit" link, the url is
http://localhost:10871/admin/Edit/e7d0c5ee-7782-411f-920e-7b0d93c924e1
and the form is displayed correctly, but the save button doesn't work, no network activity happens. Is something particular about using uniqueidentifers as primary key?
Thanks
---Code---
Edit.cshtml
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Domain</legend>
@Html.HiddenFor(model => model.GUID)
@Html.HiddenFor(model => model.ID)
<div class="editor-label">
@Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Description)
@Html.ValidationMessageFor(model => model.Description)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
--AdminController.cs--
// GET: /Admin/Edit/5
public ActionResult Edit(Guid id)
{
Domain domain = db.Domains.Single(d => d.GUID == id);
return View(domain);
}
//
// POST: /Admin/Edit/5
[HttpPost]
public ActionResult Edit(Domain domain)
{
if (ModelState.IsValid)
{
db.Domains.Attach(domain);
db.ObjectStateManager.ChangeObjectState(domain, EntityState.Modified);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(domain);
}
Edit2
In response to a comment by ZippyV, I added the following code in Edit.cshtml
<div class="editor-label">
@Html.LabelFor(model => model.ID)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ID)
@Html.ValidationMessageFor(model => model.ID)
</div>
to my surprise (or ignorance) - the GUID is being shown instead of ID
and apart from that - when I enter a value in that field (1,2 or any integer), I still get the message "The field ID must be a number."
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题来自这样一个事实:您的视图模型上有一个名为 ID 的属性:
同时您的
Edit
控制器操作中有一个名为id
的路由参数:现在发生的事情是这样的:Html 帮助器(例如 TextBoxFor、HiddenFor 等)在绑定值(即查询字符串参数、路由值)时总是首先查看模型状态,并且仅在最后才查看中的值模型。这就是所有 Html 助手的工作方式,也是设计使然。
因此,您有以下内容:
ID 不是从模型中获取,而是从您的路线数据(这是您的操作参数中指定的 Guid)中获取。这就是为什么在视图模型和操作参数中使用同名的属性是非常危险的。
一种可能的解决方法是将操作参数重命名为其他名称:
当然,现在您的路由可能需要调整或使用查询字符串参数:
controller/edit?domainId=d578b4b7-48ec-4846-8a49-2120c17b6441 调用编辑操作。
The problem comes from the fact that you have a property called ID on your view model:
and at the same time you have a route parameter called
id
in yourEdit
controller action:Now here's what happens: The Html helpers (such as TextBoxFor, HiddenFor, ...) always first looks in the model state when binding a value (i.e. query string parameters, route values) and only at the end it looks at the value in the model. That's how all Html helpers work and it is by design.
So you have the following:
The ID is taken NOT from the model but from your Route data (which is a Guid as specified in your action parameter). That's why it is very dangerous to use properties in the view model and action parameters that have the same name.
One possible workaround would be to rename your action parameter to something else:
Of course now your routes might need to be adapted or use query string parameters:
controller/edit?domainId=d578b4b7-48ec-4846-8a49-2120c17b6441
to invoke the Edit action.