如果未绑定,MVC4 Razor会丢失UserID

时间:2012-10-11 10:41:53

标签: asp.net-mvc data-binding razor model

我现在正在MVC4中创建一些用户配置文件编辑表单并进行测试我将UserId属性呈现为表单上的只读文本框,如下所示:

<li>
    @Html.LabelFor(model => model.UserId)
    @Html.TextBoxFor(model => model.UserId, new { @readonly="readonly"})
</li>

当我即将完成编辑表格时,我删除了这个文本框,因为它只是用尽了房地产。一旦我完成了这个,模型发送回控制器时保存的整数默认值为0,然后实体框架爆炸,因为它无法更新任何行。所以我将其添加到表单中:

<li>
    @Html.HiddenFor(model => model.UserId, new { @readonly="readonly"})
</li>

这是安全举措吗?我应该使用ViewBag这样的事情吗?在配置文件详细信息页面上,我渲染了一个如下的编辑按钮:

@Html.ActionLink("Edit", "Edit", new { id=Model.UserId })

表示UserId在链接中呈现。这是安全的还是我需要重新思考如何在UI周围移动模型和ID?

TIA,

3 个答案:

答案 0 :(得分:2)

  

这是安全举措吗?

这将完成将id发送到服务器的工作。只需摆脱readonly="readonly"属性,这对于隐藏输入几乎没有意义。

  

我应该像这样使用ViewBag吗?

这在安全性方面没有任何改变。任何用户仍然可以放置他想要的任何ID。无论您是使用隐藏字段还是ActionLink,您仍然将id作为纯文本发送到服务器,任何人都可以伪造请求并输入他想要的任何ID。因此,如果您的站点使用某种形式的身份验证,则必须在服务器端检查您在尝试对其执行任何操作之前,实际收到的ID实际上是属于当前已验证用户的资源。否则,一些经过身份验证的用户可以提供属于另一个用户的资源的ID,并且能够更新它。当然这只是一个假设情景,根本不清楚这是否是你的情况以及这个id是否需要得到保障。

答案 1 :(得分:1)

如果UserId是敏感的,那么还有其他选项

  • 仅将UserId服务器端保留为会话状态(如果您的架构允许Session
  • 将其放入encrypted cookie。请注意,根据Darin,这些可以是compromised

如果它不敏感,那么您的HiddenFor就可以了 - 将其与表单的其余部分一起发回。 不要将它放在你的ActionLink Querystring中,除非这是你的路线的一部分(即/ Controller / Action / id)

答案 2 :(得分:0)

我强烈建议使用ValueInjecter。这是一个执行相同操作的代码片段

[HttpGet]
    public new ActionResult Profile()
    {
        var model = new ProfileModel();

        model.InjectFrom<UnflatLoopValueInjection>(this.GetCurrentUser());

        return View(model);
    }

    [HttpPost]
    public new ActionResult Profile(ProfileModel model)
    {
        if (ModelState.IsValid)
        {
            this.GetCurrentUser().InjectFrom<UnflatLoopValueInjection>(model);

            try
            {
                _userService.SaveOrUpdate(this.GetCurrentUser());
                TempData["Success"] = "User was successfully updated.";
                return RedirectToAction("Profile");
            }
            catch (Exception)
            {
                ModelState.AddModelError("Exception", "Unexpected error");
            }
        }

        return View(model);
    }

以下是观点......

    @using (Html.BeginForm("Profile", "Account", FormMethod.Post, new { @class = "form-horizontal" }))
{
    @Html.ValidationSummary(true, "Unable to update profile. Please correct the errors and try again.", new { @class = "alert alert-block alert-error" })

    @Html.EditorForModel()

    <div class="form-actions">
        <input type="submit" value="Update" class="btn btn-primary" />
    </div>        
}