处理模型的多个复选框的简明方法

时间:2014-03-11 12:24:25

标签: c# asp.net-mvc entity-framework

我有两个类,歌曲和标签。这种关系是多对多的。我遇到的问题是,当用户添加新歌并检查他/她想要的标签时,我在控制器中调用db.SaveChanges(),它会添加重复的标签,而不是仅向连接表添加记录。我已经解决了这个问题,但这是一个黑客攻击。必须有更好的解决方案吗?

这是我的代码(为了清晰起见而缩略)。

曲:

public int Id { get; set; }
public List<Tag> Tags { get; set; }
public string SongTitle { get; set; }

标签:

public int Id { get; set; }
public string TagName { get; set; }
public bool Selected { get; set; }
public List<Song> Songs { get; set; }

控制器:

public ActionResult Create()
{
    Song song = new Song();
    song.Tags = utilities.TagNames(_db, User.Identity.Name);
    return View(song);
}

[HttpPost]
public ActionResult Create(Song song)
{
    //cycle thru the tags and grab ids of checked tags
    int tagCount = song.Tags.Count;
    List<int> tagIds = new List<int>();
    for (int i = tagCount - 1; i > -1; i--)
    {
        Tag tag = song.Tags[i];
        if (tag.Selected)
            tagIds.Add(tag.Id);
    }
    song.Tags = null;

    if (ModelState.IsValid)
    {                
        _db.Songs.Add(song);
        _db.SaveChanges();
        int songId = song.Id;

        string sql = "INSERT INTO [dbo].[TagSongs] (Tag_Id, Song_Id) VALUES ";
        foreach(int tagid in tagIds)
        {
            sql += "(" + tagid + "," + songId + "),";
        }
        //remove the last comma
        sql = sql.Substring(0, sql.Length - 1);
        _db.Database.ExecuteSqlCommand(sql);

        return RedirectToAction("Index");
    }
    SetCategoriesAndTags(song);
    return View(song);
}

查看:

@for (int i = 0; i < Model.Tags.Count; i++)
{
    Tag t = Model.Tags[i];
    @Html.CheckBoxFor(m => m.Tags[i].Selected)
    <label for="Tags_@i.ToString()__Selected">@t.TagName</label>
    @Html.HiddenFor(m => m.Tags[i].Id)

    @Html.HiddenFor(m => m.Tags[i].TagName)
}

1 个答案:

答案 0 :(得分:0)

首先,不要对SQL查询使用字符串连接,否则会打开SQL注入攻击。这段代码可以满足您的需求。从控制器ActionMethod中调用它。

private void AddSongs(Song song, List<int> tagIds)
{
    _db.Songs.Add(song);
    foreach(var tagId in tagIds)
    {
        var tag = _db.Tags.SingleOrDefault(tagId);

        if(tag != null) song.Tags.Add(tag);
    }
    _db.SaveChanges();
}