Entity framework EF代码第一个MVC4-ArgumentNullException on edit-我在这里做错了什么?
假设我有3个模型:Entity framework EF代码第一个MVC4-ArgumentNullException on edit-我在这里做错了什么?,entity-framework,asp.net-mvc-4,ef-code-first,Entity Framework,Asp.net Mvc 4,Ef Code First,假设我有3个模型: [Table("UserProfile")] public class UserProfile //this is a standard class from MVC4 Internet template { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int UserId { get; set; } public string User
[Table("UserProfile")]
public class UserProfile //this is a standard class from MVC4 Internet template
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
public class Post
{
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
public int UserProfileId { get; set; }
[ForeignKey("UserProfileId")]
public virtual UserProfile UserProfile { get; set; }
}
我得到了一个例外。
快速查看调试,我可以知道我的Category为null,尽管CategoryId设置为正确的值
这句话的意思是,“难看的把戏”解决了这个问题,但我想它根本不应该存在。所以问题是如何正确地解决它
我会说这是EF延迟加载的原因,因为我有非常相似的代码用于添加Post,在调试中有相同的场景:正确的CategoryId,Category为null,尽管EF自动解决了Post类别依赖性,我不必使用任何额外的技巧。
在编辑方法上,EF有一些问题,但我无法找出我做错了什么。这是按预期工作的。您的
Post
对象未附加到上下文,因此它没有理由执行任何延迟加载。这是完整的密码吗?我不明白为什么您需要将Category设置为Modified
,因为您实际上并没有对其进行任何更改
无论如何,我建议您从数据库中查询现有帖子,并指定要让用户修改的相关字段,如:
[HttpPost]
public ActionResult Edit(Post post)
{
var existingPost = context.Posts
.Where(p => p.Id == post.Id)
.SingleOrDetault();
if (existingPost == null)
throw new HttpException(); // Or whatever you wanna do, since the user send you a bad post ID
if (ModelState.IsValid)
{
// Now assign the values the user is allowed to change
existingPost.SomeProperty = post.SomeProperty;
context.SaveChanges();
return RedirectToAction("Index");
}
return View(post);
}
通过这种方式,您还可以确保用户试图编辑的帖子确实存在。仅仅因为您收到了一些操作参数,并不意味着它们是有效的,或者帖子的Id是真实的。例如,一些恶意用户可能会决定编辑他不允许编辑的帖子。你需要检查一下这类事情
更新
另一方面,您还可以避免手动查询当前用户的Id。如果您使用的是简单成员身份
,则可以通过WebSecurity.CurrentUserId
如果您使用的是
表单身份验证
,则可以执行Membership.GetUser().ProviderUserKey
是的!:)从DB获取post成功了,lazy正在按预期工作。不,这不是完整的代码,我尽量保持简单。看起来根本不需要“修改”。这个答案正是我所期望的——如何正确处理这个问题的总体思路。谢谢:)
[HttpPost]
public ActionResult Edit(Post post)
{
var existingPost = context.Posts
.Where(p => p.Id == post.Id)
.SingleOrDetault();
if (existingPost == null)
throw new HttpException(); // Or whatever you wanna do, since the user send you a bad post ID
if (ModelState.IsValid)
{
// Now assign the values the user is allowed to change
existingPost.SomeProperty = post.SomeProperty;
context.SaveChanges();
return RedirectToAction("Index");
}
return View(post);
}