2012-05-31 1 views
8

Я начал использовать MVC недавно, и я немного разочарован. Вместо того, чтобы помогать мне, рамки мешают мне.Как получить контроль над привязкой модели?

Я пытаюсь написать действие контроллера, как это (псевдокод)

ActionResult Save(long id, string whichForm) 
{ 
    if (whichForm == "A") 
    { 
     var vm = CreateModel(Request.Form); 
     if (!TryValidate(vm)) 
      return View(vm); 
     else 
      return RedirectToRoute("Success"); 
    } 
    else .... 
} 

В основном я хотел бы иметь контроль над тем, когда строится мой взгляд, модель и когда она утверждена. Это возможно? Как я могу реализовать метод CreateModel? Подумайте, я могу создать несколько разных моделей представлений в рамках этого действия контроллера.

* Rant: Я действительно не понимаю, почему привязка и проверка привязки модели используются в DefaultModelBinder. Похоже на запах кода. Специально, когда трудно переопределить это поведение.

+1

Спасибо, что обратились к нисходящим каналам, не забудьте оставить комментарий? :-) – Kugel

+0

+1 Может, им не понравился ваш * Rant, но вы имеете право на свое мнение, и я не вижу ничего плохого в этом вопросе. Если вопрос приводит к хорошим ответам, то вопрос в порядке ИМО. – AaronLS

ответ

16

Вы можете создать и привязать к существующей модели на ваше усмотрение:

public ActionResult Save(long id, string whichForm) 
{ 
    if (whichForm == "A") 
    { 
     var vm = new FormAViewModel(); 

     if (!TryUpdateModel(vm)) 
      return View(vm); 
     else 
      return RedirectToRoute("Success"); 
    } 
    // else .... 
} 

You also have the option of creating your own IModelBinder, если вы хотите полный контроль над процессом обвязки. Вы можете заменить привязку модели по умолчанию, или вы можете зарегистрировать конкретные версии IModelBinder для определенных типов. Я бы предположил, однако, что, если ваша логика привязки проста, вы, вероятно, захотите получить свое пользовательское связующее устройство от DefaultModelBinder и просто переопределите части, которые вам не нравятся.

Ненавижу оставлять комментарий тролля, но 9 раз из 10 причин, по которым кто-то чувствует, что рамки мешают им, потому что они еще не понимают, как правильно его использовать. Here is an article with general tips on model binding.

Что касается вашей напыщенности: проверка и привязка раздельны, однако связующее устройство по умолчанию вызывает проверку. Причина этого заключается в том, чтобы позволить вашему приложению грамотно обрабатывать проблемы, связанные с отсутствующими/недостоверными/неполными значениями, вместо того, чтобы разрешать привязку к отказу молча или исключение.

+0

Большое спасибо, я полностью пропустил метод TryUpdateModel. И поверьте мне, что я искал довольно долгое время и прочитал все о DefaultModelBinder и IModelBinder. Также просмотрел исходный код MVC ... – Kugel

0

Вы можете использовать интерфейс IModelBinder и написать полное пользовательское связывание модели. Здесь это объясняется хорошо. По сути, этот интерфейс предоставляет метод «BindModel», где вы можете контролировать поведение привязки модели наряду с проверкой.

http://www.dotnetcurry.com/ShowArticle.aspx?ID=584

Однако это может усложнить этот вопрос, и вы могли бы получить в запутанном коде. Я бы предложил простой «Action per model», если он вас устроит. Таким образом, вы можете написать примерно так:

ActionResult SaveA(long id, AViewModel) 
{ 
     //.... Action to be conducted in case it is form A. 
} 
ActionResult SaveB(...., BViewModel) 
{ 
     //... Action to be conducted in case it is form B. 
} 


// Your view models can be structured for code reuse as well. 
class AViewModel { ... } 
class BViewModel : AViewModel { ... } 
+0

Извините, но вы пропустили мой вопрос. – Kugel