11

簡単に言えば、何をするのUpdateModel()ですTryUpdateModel()か?私は(SOまたはWeb上で)それが実際に何をするのか(明確な言葉で)の明確な説明を見つけることができないようです.それを使用するのに問題がある人だけです.

VisualStudio のインテリセンスも役に立ちません。私が尋ねる理由は、たとえば、コントローラーにこれがある場合:

[HttpPost]
public ActionResult Index( UserViewModel vm, FormCollection form)
{    
  var statesCheckBoxes = form["StatesList"];       

  vm.BA.StatesTraveledTo = statesCheckBoxes.Split(',').ToList<string>();

  return View(vm);
}

を設定してモデルを既に更新していませんvm.BA.StatesTraveledToか? UpdateModel を実行する必要があるのはなぜですか? また、実際に次のことをしようとすると:

[HttpPost]
public ActionResult Index( UserViewModel vm, FormCollection form)
{    
  var statesCheckBoxes = form["StatesList"];       

  vm.BA.StatesTraveledTo = statesCheckBoxes.Split(',').ToList<string>();

  UpdateModel(vm); // IS THIS REDUNDANT TO THE PREVIOUS LINE?

  return View(vm);
}

ModelState の値を調べると ( UpdateModel() を実行した後)、何かが変更されたことを示すものは何も表示されません。ModelState ディクショナリに新しいキーがありません。

本当に混乱しています。ありがとう!

編集:

ViewModel および Model クラスのソース コードを投稿します。

public class UserViewModel
{
  public BankAccount BA { get; set; }
}

public class BankAccount
{
  public Person User { get; set; }
  public List<string> StatesTraveledTo { get; set; }
}

public class Person
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public int Age { get; set; }
}
4

3 に答える 3

7

what happens when you write

public ActionResult Index( UserViewModel vm)
{    }

and when you inspect in the ActionResult you find that vm contains values that you posted from the view. it is because mvc directs the modelbinder to extract values from different sources (form collection, route values, querystring etc) and populate values of your model. But for this to happen your form keys must match the name of properties in your model and if that is the case your model is populated correctly. now we come to the actual question: what does UpdateModel do? simple answer is nothing but model binding. The difference is only that you call it explicitly. The above ActionResult can be rewritten like using UpdateModel

Public ActionResult Index ()
{
   UserViewModel vm = new UserViewModel();
   UpdateModel(vm);// it will do same thing that was previously handled automatically by mvc
}

Now, what was not handled by automatic model binding will not be handled by explicit model binding as well because its not the problem with model binder its the problem with your html. with nested view models like yours, the form field names must be carefully crafted so mvc can correctly inject it to your model without you having to write something like

vm.BA.StatesTraveledTo = statesCheckBoxes.Split(',').ToList<string>(); 

and if you don't want to do such thing check this google search

于 2011-12-22T11:08:48.367 に答える
2

ソースコードは次のとおりです。http://aspnet.codeplex.com/SourceControl/changeset/view/72551#266451

とてもシンプルです。

    protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties, IDictionary<string, ValueProviderResult> valueProvider) where TModel : class {
        if (model == null) {
            throw new ArgumentNullException("model");
        }
        if (valueProvider == null) {
            throw new ArgumentNullException("valueProvider");
        }

        Predicate<string> propertyFilter = propertyName => BindAttribute.IsPropertyAllowed(propertyName, includeProperties, excludeProperties);
    IModelBinder binder = Binders.GetBinder(typeof(TModel));

    ModelBindingContext bindingContext = new ModelBindingContext() {
        Model = model,
        ModelName = prefix,
        ModelState = ModelState,
        ModelType = typeof(TModel),
        PropertyFilter = propertyFilter,
        ValueProvider = valueProvider
    };
    binder.BindModel(ControllerContext, bindingContext);
    return ModelState.IsValid;
}

これは、ModelBindingContext を作成してバインドするだけです。アクションが呼び出される前に、デフォルトですでに発生していると思います。手動で呼び出す必要があることはめったにありません。

ここでは推測にすぎませんが、通常とは異なる方法で行っているため、奇妙な結果が得られる可能性があります。アクションの署名:

public ActionResult Index( UserViewModel vm, FormCollection form)

UserViewModel と FormCollection を取ります。通常、人々はどちらか一方を行います (実際、FormCollection は最近では非常にまれです)。繰り返しますが、ここでメモリをオフにしますが、これらの値は既にバインドされているため、UpdateModel は何もしないと思います。空の場合は、FormCollection がすべての submittd 値を受け取り (バインド)、viewmodel がバインドする値が何も残っていないことが原因である可能性があります。

于 2011-12-22T06:57:43.877 に答える
0

モデルの更新は基本的に、既存のモデルの新しい値を更新するために使用されます。値を明示的に割り当てる必要はありません。

于 2011-12-22T07:00:17.433 に答える