使用MVC控制器的模型绑定更新编辑POST的关系 [英] Update relationships on edit POST with model bind from MVC controller

查看:186
本文介绍了使用MVC控制器的模型绑定更新编辑POST的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用具有多对多关系的实体框架,我很困惑如何从模型绑定的ASP.NET MVC控制器更新该关系。



例如,一个博客:帖子中有很多标签,标签有很多帖子。



帖子控制器编辑操作无法延迟加载标签实体:

  public class PostsController:Controller 
{
[Route post / edit / {id})]
[HttpPost]
[ValidateAntiForgeryToken]
public async任务< ActionResult>编辑([绑定(包括=Id,标题,标签)]帖子)
{
//发布标签为空
Post.tags.ToList();
}
}

以上,HTTP Post将属性绑定到模型;但是, Post.tags 关系为null。



我无法查询, .Include(p => p.Tags) Attach()该帖子以使用此 [Bind()]



在视图方面,我正在使用一个tokenizer并传递formdata - 不使用MVC列表组件。所以,问题是没有绑定视图formdata - 问题是, .tags 属性不是懒惰加载实体。



这个关系是有效的 - 从Razor cshtml视图我可以遍历集合并查看子标签。



从帖子视图,我可以查看标签(这个工程)

  @foreach(Model.Tags中的var标签){
}

从标签查看,我可以查看帖子(这个工程)

  @foreach(在Model.Posts中的var post){
}

同样,从帖子控制器创建操作,我可以创建新的标签实体并保持他们的关系。 / p>

  public class PostsController:Controller 
{
[Route(posts / create)]
[HttpPost]
[ValidateAntiForgeryToken]
public async任务< ActionResult>创建([绑定(包括=标题,内容)]帖子)
{
string [] tagNames = this.Request.Form [TagNames]。Split(',')。 (tag => tag.Trim())。ToArray();

post.Tags = new HashSet< Tag>();

标签标签= new Tag();
post.Tags.Add(tag);

if(ModelState.IsValid)
{
db.posts.Add(post);
等待db.SaveChangesAsync();
return RedirectToAction(Admin);
}

return View(post);
}

除了这个编辑HTTP Post之外,这些关系都可以使用。作为参考,它们被定义为:

  public class Post 
{
public virtual ICollection< Tag>标签{get;组; }
}

public class标签
{
public virtual ICollection< Post>帖子{get;组; }
}

只有在HTTP发布的编辑操作中,我不能访问帖子的标签。



如何加载相关标签来更改该集合?

解决方案

您的创建方法,缺少您要插入标签的帖子的ID参数。
您必须在方法开始时声明发布ID。

  [Route(posts / create) ] 
[HttpPost]
[ValidateAntiForgeryToken]
public async任务< ActionResult>创建([绑定(包括=标题,内容)]帖子)
{
Post nPost = db.Posts.FirstOrDefault(x => x.Id == post.Id);
nPost.Id = post.Id;
nPost.Title = post.Title;
string [] tagNames = this.Request.Form [TagNames]。Split(',')。选择(tag => tag.Trim())ToArray();
foreach(tagNames中的字符串项)
{
//首先检查标签表中是否有标签
标签tg = db.Tags.FirstOrDefault(x => x。 Name.ToLower()== item.ToLower()。Trim());
//如果没有行创建一个。
if(tg == null)
{
tg = new Tag();
tg.Name = item;
db.Tags.Add(tg);
等待db.SaveChanges();
}
//现在将这些标签添加到帖子标签。
if(nPost.Tags.FirstOrDefault(x => x.Id == tg.Id)== null)
{
nPost.Tags.Add(etk);
等待db.SaveChanges();
}
}
if(ModelState.IsValid)
{
等待db.SaveChangesAsync();
return RedirectToAction(Admin);
}
return View(post);
}

就是这样。


Using Entity Framework with a many-to-many relationship, I'm confused how to update that relationship from an ASP.NET MVC controller where the model is bound.

For example, a blog: where posts have many tags, and tags have many posts.

Posts controller edit action fails to lazy load tags entities:

public class PostsController : Controller
{
    [Route("posts/edit/{id}")]
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Edit([Bind(Include = "Id,Title,Tags")] Post post)
    {
        // Post tags is null
        Post.tags.ToList();
    }
}

Above, the HTTP Post binds properties to the model; however, the Post.tags relationship is null.

There's no way for me to query, .Include(p => p.Tags), or Attach() the post to retrieve the related tag entities using this [Bind()].

On the view side, I'm using a tokenizer and passing formdata - I'm not using a MVC list component. So, the issue is not binding the view formdata - the issue is that the .tags property is not lazy loading the entities.

This relationship is functional - from the Razor cshtml view I am able to traverse the collection and view children tags.

From the Post View, I can view tags (this works)

@foreach (var tag in Model.Tags) {
}

From the Tag View, I can view posts (this works)

@foreach (var post in Model.Posts) {
}

Likewise on create action from the Posts controller, I can create new tag entities and persist their relationship.

public class PostsController : Controller
{
    [Route("posts/create")]
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Create([Bind(Include = "Title,Content")] Post post)
    {
        string[] tagNames = this.Request.Form["TagNames"].Split(',').Select(tag => tag.Trim()).ToArray();

        post.Tags = new HashSet<Tag>();

        Tag tag = new Tag();
        post.Tags.Add(tag);

        if (ModelState.IsValid)
        {
            db.posts.Add(post);
            await db.SaveChangesAsync();
            return RedirectToAction("Admin");
        }

        return View(post);
    }

These relationships work everywhere except for this edit HTTP Post. For reference, they are defined as:

public class Post
{
    public virtual ICollection<Tag> Tags { get; set; }
}

public class Tag
{
    public virtual ICollection<Post> Posts { get; set; }
}

Only on HTTP Post of edit action can I not access tags of posts.

How can I load related tags to alter that collection?

解决方案

Your create method that missing an Id parametres of post that you want to insert tags. You have to declare Post Id at the begining of the method.

[Route("posts/create")]
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "Title,Content")] Post post)
{
        Post nPost= db.Posts.FirstOrDefault(x => x.Id == post.Id);
        nPost.Id= post.Id;
        nPost.Title= post.Title;
        string[] tagNames = this.Request.Form["TagNames"].Split(',').Select(tag => tag.Trim()).ToArray();
        foreach(string item in tagNames)
        {
          //First check if you got tag in Tags table
          Tag tg= db.Tags.FirstOrDefault(x => x.Name.ToLower() == item.ToLower().Trim());
          // If no row than create one.
          if (tg== null)
          {
             tg= new Tag();
             tg.Name= item;
             db.Tags.Add(tg);
             await db.SaveChanges();
           }
          // Now adding those tags to Post Tags.
           if (nPost.Tags.FirstOrDefault(x => x.Id == tg.Id) == null)
           {
              nPost.Tags.Add(etk);
              await db.SaveChanges();
           }
        }
        if (ModelState.IsValid)
        {
          await db.SaveChangesAsync();
          return RedirectToAction("Admin");
        }
    return View(post);
}

That's it.

这篇关于使用MVC控制器的模型绑定更新编辑POST的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆