asp.net mvc脚手架和GUID作为主键

时间:2011-07-20 15:59:56

标签: asp.net-mvc asp.net-mvc-3 razor uniqueidentifier asp.net-mvc-scaffolding

我有一个包含以下结构的表

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

并且表单显示正确,但保存按钮不起作用,不会发生网络活动。使用uniqueidentifer作为主键是特别的吗?

由于

--- ---代码

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的评论时,我在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>

令我惊讶(或无知) - 显示GUID而不是ID GUID is shown as ID

除此之外 - 当我在该字段中输入一个值(1,2或任何整数)时,我仍然收到消息“字段ID必须是数字。”

1 个答案:

答案 0 :(得分:7)

问题来自于您在视图模型上有一个名为ID的属性:

public class Domain
{
    public int ID { get; set; }
    ...
}

同时在id控制器操作中有一个名为Edit的路由参数:

public ActionResult Edit(Guid id)
{
    ...
}

现在发生了什么:Html助手(例如TextBoxFor,HiddenFor,...)在绑定值时(即查询字符串参数,路由值)始终首先查看模型状态,并且仅在最后看到模型中的值。这就是所有Html帮助程序的工作原理,它是设计的。

所以你有以下内容:

@Html.HiddenFor(model => model.ID)

ID从模型中获取 NOT ,但来自您的Route数据(这是您的action参数中指定的Guid)。这就是为什么在视图模型和具有相同名称的动作参数中使用属性非常危险。

一种可能的解决方法是将您的action参数重命名为其他内容:

public ActionResult Edit(Guid domainId)
{
    Domain domain = db.Domains.Single(d => d.GUID == domainId);
    return View(domain);
}

当然,现在您的路线可能需要调整或使用查询字符串参数:controller/edit?domainId=d578b4b7-48ec-4846-8a49-2120c17b6441来调用编辑操作。