我已经进行了彻底的搜索,但实际上找不到任何解决我所面临的情况的事情(奇怪的是因为我认为这是很常见的事情)。
我正在使用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
为false,因为没有从视图传入UserId。显然,因为不希望用户输入他们的ID。
我已经尝试将ID值放入ViewBag
并在视图中使用@Html.Hidden()
字段,但是我没有成功。 Model.IsValid
始终返回false。
是否应通过创建视图输入此信息?或者应该直接在控制器中完成?这是一个非常令人沮丧的问题,因为我有信息,只需要知道如何将其传递到模型中。
这基本上只是默认的脚手架代码。注释代码是我尝试直接从控制器设置模型值的方式,但这只是试验和错误。
//
// 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);
}
答案 0 :(得分:3)
小心隐藏的字段。任何人都可以在该领域中放置他们想要的任何价值(即他们可以欺骗另一个用户)。您最好在登录时缓存会话中的ID,并使用该值。
答案 1 :(得分:2)
这是一种典型的情况,您希望在视图和控制器层之间创建EditModel
作为数据传输对象(DTO)。
创建一个类BlogPostEditModel
,其中包含用户在创建新博客帖子时需要填写的所有属性。然后,将此类型(例如,使用AutoMapper)映射到BlogPost
实体,并填写用户ID。
要使用内置验证(例如Model.IsValid()
),请将数据注释属性放在DTO上。
答案 2 :(得分:2)
老实说,我会通过控制器分配值。如果你有人通过Firebug弄乱你的html,他们实际上可以在传递之前更改id并提交给你的表单。我会从你的创建视图中删除它并从控制器提交。