0

ビューから変更されたモデルの値のみを追跡することは可能ですか。たとえば、私はモデルという名前を持っていますSampleModel

public class SampleModel
{
   public int Id { get; set; }
   public string ImageUrl1 { get; set; }
   public string ImageUrl2 { get; set; }
}

コントローラー内の変更されたモデル値のみを確認する方法は?

4

4 に答える 4

2

コントローラーは、リクエストから入ってくる値のみを認識します。何が変更されたかを確実に判断するには、受け取ったモデルを、コントローラー アクション ロジックまたはビジネス レイヤー ロジックの (リポジトリ/dao/dal/whatever) から取得した現在のモデルと比較する必要があります。

于 2013-08-05T06:03:47.370 に答える
0

いくつかのオプションがありますが、これを行うネイティブな方法はありません。使用している永続化フレームワーク (ef、linq2sql、lightspeed、subsonic など) を教えてくれないので、そのフレームワークからネイティブな方法があるかどうかはわかりません。

  1. 開始モデルをフォーム フィールドとしてシリアル化します。サーバー側でそれを逆シリアル化し、MVC が POST から提供したモデルと比較します。私は通常 Newtonsoft.Json を使用し、それを UrlEncode します。

  2. モデル フィールドごとに を追加<input name="field_original" value="....">し、サーバー側で一度に 1 つずつ比較します。Model.Name == Form["name_original"]

  3. jQuery を使用して、入力が変更されたかどうかを追跡し、非表示の入力として保存します。例えばif (Form["name_modified"] == "true")) { _save name_ }

  4. jQuery を使用して、その他の高度な追跡システムを実行します。選択肢が多すぎます。たとえば、元の値を持つ各入力に「data-originalValue」属性を追加できます。次に、フォームを送信する前に、各項目を確認<input>し、変更されたプロパティの名前で別の項目を更新できます。

  5. モデルの元となった元のエンティティをデータ ストアから取得します。各フィールドを手動で確認し、変更されたものだけを更新します。

  6. 永続化レイヤーが変更追跡をサポートしている場合 (EF など)

  7. 元のエンティティを取得する

  8. モデルの値でエンティティの値を更新します

  9. 既存のものと同じ値を設定しても、プロパティが変更済みとしてマークされないことを確認してください

  10. エンティティを保存します (変更されたフィールドのみを保存する必要があります)。

###上記の #1 の例

<form ...>
    <input type="hidden" name="OldModel" value="@Url.Encode(JsonConvert.SerializeObject(Model))"/>
    <!-- the rest of  your model fields --!>
    @Html.TextBoxFor(m => m.Url)
コントローラーの方法
using Newtonsoft.Json;

[HttpPost]
public ActionResult Save(MyModel model) {
    var oldModel = JsonConvert.DeserializeObject<MyModel>(
                        HttpUtility.UrlDecode(Request.Form["OldModel"]));
    if (oldModel.Url != model.Url) { 
        // code to save the Url field only
    }
}
于 2013-08-05T07:00:15.017 に答える
0

次に、何らかの形式の DTO パターンが必要になる場合があります。

たとえば、「作成」アクションと「編集」アクションに異なるフォームが必要な場合は、次のようにします。

新しいフォームの 1 つのクラス:

public class NewSampleModelDto
{
   [Required]
   public string ImageUrl1 { get; set; }

   public NewSampleModelDto() { }

   public SampleModel ToModel() 
   {    
        return new SampleModel 
        { 
            ImageUrl1 = ImageUrl1
        };
   {
}

編集フォーム用の 1 つのクラス:

public class EditSampleModelDto
{
   public int Id { get; set; }

   [Required]
   public string ImageUrl2 { get; set; }

   // default constructor required for mvc model binding
   public EditSampleModelDto() { }

   // from model ==> dto
   public EditSampleModelDto(SampleModel sampleModel) 
   { 
        Id = sampleModel.Id;
        ImageUrl2 = sampleModel.ImageUrl2;
   }

   // from dto ==> model
   public void UpdateModel(SampleModel sampleModel) 
   {    
        sampleModel.ImageUrl2 = ImageUrl2;
   {
}

これにより、フォームごとにカスタム検証ロジックを定義できるという柔軟性が得られます。コードを DRY に保つために、すべての 'model ==> dto' ロジックを処理するコンストラクターを提供するベース SampleModelDto を作成できます。ここでプロパティに表示属性を設定することもできます。

とにかく、これらの DTO をフォームで使用してコントローラーに送信すると、検証と更新ロジックをより自由に指定できます。

于 2013-08-05T06:17:39.827 に答える
0

あなたが何を望んでいるかを正しく理解していれば、この目的のために jQuery を使用できます。たとえば、古い値に対して非表示の div を作成し、それを現在の値と比較することができます。現在の値が古い値と等しい場合は、投稿する必要はありません。

<script>
$('oldValue').hide();

$(#ok).click(function())
{
var ImageUrl1;
if ($(newValue).val() != $(oldValue).val())  
    $post(.....)
});

</script>


<div class="oldValue">@Model.ImageUrl1</div>
<div class="newValue">........</div>

<button id="ok">ok</button>
于 2013-08-05T06:28:34.890 に答える