-2

MVC4コントローラーにデータを投稿すると、既存のレコードを使用する必要があるときに新しいレコードが作成される理由を理解しようとしています。

私のコントローラーは次のとおりです。

    public ActionResult Edit(Song song) {
    JsonBase jsonBase;
    var dbSong = _songRepository.FindById(song.Id);
    TryUpdateModel(dbSong, String.Empty, null, new String[] { "CreatedDate", "SongAlternateTitles", "SongWriterSongs", "Exploitations" });
    if (ModelState.IsValid) {
        _unitOfWork.Commit();
        jsonBase = new JsonBase(true, null, new { Id = dbSong.Id });
    }
    else {
        jsonBase = new JsonBase(false, ModelState.Values);
    }
    return Json(jsonBase);
}

Songオブジェクトは次のようになります。

public class Song : IEntity
{
    public virtual Int32 Id { get; set; }

    [Required]
    [StringLength(128, ErrorMessage = "Song Title cannot exceed 128 characters")]
    public virtual String Title { get; set; }

    [Required]
    [StringLength(512, ErrorMessage = "Song Description cannot exceed 512 characters")]
    public virtual String Description { get; set; }

    [StringLength(8000, ErrorMessage="Song lyrics cannot exceed 4096 characters")]
    public virtual String Lyrics { get; set; }

    [Required]
    [Display(Name="Song Status")]
    public virtual Boolean isMaster { get; set; }

    [StringLength(256, ErrorMessage = "File Path cannot exceed 256 characters.")]
    public virtual String AudioFilePath { get; set; }

    [StringLength(256, ErrorMessage = "File Path cannot exceed 256 characters.")]
    public virtual String CoverImageFilePath { get; set; }

    public virtual DateTime CreatedDate { get; set; }

    public virtual Int32? BPM { get; set; }

    public virtual ICollection<Tag> Tags { get; set; }
    public virtual ICollection<SongAlternateTitles> SongAlternateTitles { get; set; }
    public virtual ICollection<Exploitation> Exploitations { get; set; }
    public virtual ICollection<SongWriterSong> SongWriterSongs { get; set; }
    public virtual ICollection<Tweak> Tweaks { get; set; }
}

次のようなJSONデータを渡します。

{"id":681,"title":"Another You","description":"Cascada - Everytime We Touch","lyrics":"","ismaster":false,"audiofilepath":"http://songistry.blob.core.windows.net/audiosamples/3211556309.mp3","coverimagefilepath":"http://songistry.blob.core.windows.net/coverimages/2711679216.jpg","tags":[{"id":43,"name":"Edgy","description":"This music is on the edge!","valid":true,"editing":false,"checked":true},{"id":44,"name":"Pop","description":"This music pops!","valid":true,"editing":false,"checked":true},{"id":47,"name":"Positive","description":"Positive","valid":true,"editing":false,"checked":true},{"id":45,"name":"Quirky","description":"Quirky","valid":true,"editing":false,"checked":true},{"id":46,"name":"R&B","description":"R&B","valid":true,"editing":false,"checked":true}],"songalternatetitles":[],"exploitations":[],"songwritersongs":[{"Id":742,"Pro":{"Id":2,"Name":"ASCAP"},"Publisher":{"Id":2,"Name":"Some Publisher","Phone":"4035555555","ContactName":"Some Guy","ContactEmail":"guy@songistry.com","ContactPhone":"4035555555","Address":"123 fake street"},"Percentage":100,"SongWriter":{"Id":1,"FirstName":"Mike","LastName":"Cottingham","Name":"Mike Cottingham","Pro":{"Id":2,"Name":"ASCAP"},"Publisher":{"Id":2,"Name":"Some Publisher","Phone":"4035555555","ContactName":"Some Guy","ContactEmail":"guy@songistry.com","ContactPhone":"4035555555","Address":"123 fake street"}}},{"Id":771,"Pro":{"Id":206,"Name":"ACUM"},"Publisher":{"Id":2,"Name":"Some Publisher","Phone":"4035555555","ContactName":"Some Guy","ContactEmail":"guy@songistry.com","ContactPhone":"4035555555","Address":"123 fake street"},"Percentage":0,"SongWriter":{"Id":8,"FirstName":"Jessica","LastName":"Cottingham","Name":"Jessica Cottingham","Pro":{"Id":1,"Name":"Socan"},"Publisher":{"Id":2,"Name":"Some Publisher","Phone":"4035555555","ContactName":"Some Guy","ContactEmail":"guy@songistry.com","ContactPhone":"4035555555","Address":"123 fake street"}}}]}

既存のレコードを使用する必要がある場合、タグ用に新しいレコードが作成されています。私は何が間違っているのですか?IDを含むタグを渡すと、モデルバインダーが自動的にそれを把握すると想定しました。

4

1 に答える 1

1

モデル バインダーは ID について何も知りません。IDさえも知りません。したがって、JSON からの変更を Tags コレクションにマージすることはできません。

エンティティに直接バインドする方法で解決策があるかどうかはわかりません。構造全体のビュー モデルを作成することをお勧めします (ビュー モデル クラスは単純な DTO であるため、これはそれほど手間がかかりません)。次に、変更を手動でマージする必要があります。これには、おそらくビュー モデル タグとエンティティ タグの間の結合が含まれます。

最初は面倒に思えますが、これは優れたシステムです。それはあなたに完全なコントロールを与えます。「タグ名が変更された場合に限り、TagNameChangeDateTime を UtcNow に設定します」などのプロセスを追加することもできます。そのようなことを行うためにバインディングを拡張することはできません。

于 2013-02-17T08:49:26.713 に答える