3

我已经进行了彻底的搜索,但真的找不到任何解决我面临的场景的东西(奇怪的是,因为我认为这是一件很常见的事情)。

背景

我正在使用 ASP.NET MVC 4 和 Entity Framework 5 Code First 创建一个应用程序。出于这个问题的目的,将其视为一个包含帖子和用户的博客应用程序。

项目

帖子模型要求每个帖子都有一个对应的 UserId。

使用 ASP.NET MVC 4 Membership 很容易找到登录用户的用户名

User.Identity.Name.

这并不理想,我们想要 ID,但是这样的查询可以在 db 中搜索名称并获取 ID。

db.UserProfiles.Single(a => a.UserName == User.Identity.Name);

问题

尝试创建帖子时会出现问题。Model.IsValid为假,因为没有从视图传入 UserId。显然,因为不希望用户输入他们的 ID。

我尝试将 ID 值放入ViewBag并使用@Html.Hidden()视图中的字段,但是我没有成功。Model.IsValid总是返回假。

是否应该通过创建视图输入此信息?还是应该直接在控制器中完成?这是一个非常令人沮丧的问题,因为我有信息并且只需要弄清楚如何将其传递到模型中。

控制器代码

这基本上只是默认的脚手架代码。注释代码是我尝试直接从控制器设置模型值的方式,但这只不过是反复试验。

    //
    // POST: /Post/Create

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(Post post)
    {
        if (ModelState.IsValid)
        {
            //var userId = db.UserProfiles.Single(a => a.UserName == User.Identity.Name);
            //post.User.UserId = userId.UserId;
            db.Posts.Add(post);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(post);
    }
4

3 回答 3

3

小心隐藏字段。任何人都可以在该字段中输入他们想要的任何值(即他们可以欺骗另一个用户)。您最好在登录时在会话中缓存 ID,并使用该值。

于 2013-03-26T17:41:54.020 回答
2

EditModel这是您想要在视图层和控制器层之间创建数据传输对象 (DTO)的典型情况。

创建一个类,该类BlogPostEditModel具有您在创建新博客文章时需要用户填写的所有属性。然后,将此类型(例如使用 AutoMapper)映射到您的BlogPost实体,并同时填写用户 ID。

要使用内置验证,例如Model.IsValid(),请将数据注释属性放在 DTO 上。

于 2013-03-26T17:41:56.133 回答
2

老实说,我会通过控制器分配值。如果有人通过 Firebug 弄乱了您的 html,他们实际上可以在 id 被传递并提交给您的表单之前更改它。我会将其从您的创建视图中删除并从控制器提交。

于 2013-03-26T17:42:41.083 回答