Литмир - Электронная Библиотека

public class UserDataBinder : IModelBinder

{

  public object BindModel(ControllerContext controllerContext,

         ModelBindingContext bindingContext)

  {

    UserData userData = new UserData();

    userData.UserId = new

       Guid(controllerContext.HttpContext.Request["UserId"]);

    userData.Email = controllerContext.HttpContext.Request["Email"];

    userData.Comment =

       controllerContext.HttpContext.Request["Comment"];

    userData.IsApproved =

       controllerContext.HttpContext.Request["IsApproved"] != "false";

    userData.IsLockedOut =

       controllerContext.HttpContext.Request["IsLockedOut"] != "false";

    MembershipProvider mp = Membership.Provider;

    userData.CurrentMembershipUser =

       mp.GetUser(userData.UserId, false);

    return userData;

  }

}

Обратите внимание на то, что при реализации своего механизма Model Binding мы сами указываем, какие параметры запроса и каким образом соответствуют ожидаемому комплексному типу вызываемого действия. Для того чтобы использовать эту реализацию интерфейса IModelBinder, мы должны зарегистрировать ее в Global.asax с помощью следующей конструкции:

protected void Application_Start()

{

  ...

  ModelBinders.Binders.Add(typeof(UserData), new UserDataBinder());

}

Здесь мы добавляем в коллекцию еще один вариант Model Binder, который призван выполнять сопоставление типа UserData для всех действий любого контроллера в приложении.

Другим вариантом подключения нашего класса UserDataBinder может стать использование атрибута ModelBinderAttribute, в этом случае мы сможем явно указать, для какого конкретного параметра нужно использовать свой вариант Model Binder. ModelBinderAttribute позволяет более гибко управлять тем, когда и как применяются пользовательские элементы Model Binder, что не редко может быть полезным. При этом регистрировать в Global.asax UserDataBinder не потребуется. Используется атрибут ModelBinderAttribute следующим способом:

public ActionResult Update(

  [ModelBinder(typeof(UserDataBinder))]  UserData userData)

Как вы видите, в данном случае атрибут использован для конкретного параметра одного-единственного действия.

В общем случае использование стандартного варианта Model Binding в виде класса DefaultModelBinder достаточно для осуществления сопоставления параметров запроса и параметров метода действия. Однако существует еще одна полезная функция механизма Model Binding в MVC Framework. Эта функция реализуется атрибутом BindAttribute и позволяет еще более гибко настраивать процесс сопоставления параметров по умолчанию. Атрибут BindAttribute имеет следующие параметры:

□ Prefix — позволяет переопределить префикс при сопоставлении по умолчанию;

□ Include — позволяет определить список допустимых параметров, которые будут участвовать в сопоставлении, остальные параметры, не входящие в этот список, рассматриваться не будут;

□ Exclude — позволяет определить "черный" список параметров, которые не должны участвовать в процессе сопоставления. Такие параметры будут игнорироваться.

Использование параметра Prefix позволяет применять в представлении префикс для элементов формы, отличный от имени параметра метода действия. Например, вместо префикса userData в рассмотренном ранее примере, мы могли бы использовать сокращенный префикс ud, определив все элементы управления формы в подобном виде:

<%= Html.Hidden("ud.UserId", (Guid)user.ProviderUserKey)%>

Чтобы механизм Model Binder по умолчанию узнал про наш новый префикс, необходимо задать атрибут BindAttribute в требуемом месте при определении параметров метода действия:

public ActionResult Update([Bind(Prefix = "ud")] UserData userData)

Параметры Include и Exclude атрибута BindAttribute могут быть полезны в тех случаях, когда необходимо избежать автоматического сопоставления в комплексном типе для каких-то определенных свойств. Это может потребоваться для обеспечения безопасности или по каким-то другим соображениям. Например, чтобы запретить сопоставление свойства IsLockedOut, мы можем указать атрибут BindAttribute следующим образом:

public ActionResult Update(

  [Bind(Exclude = "IsLockedOut")] UserData userData)

Иногда требуется задать определенный список разрешенных для сопоставления параметров. Для этого используется параметр Include, которому можно задать список разрешенных для сопоставления свойств. В следующем примере мы разрешаем для сопоставления только два свойства: Userid и Email:

public ActionResult Update(

  [Bind(Include = "UserId, Email")] UserData userData)

Механизм сопоставления комплексных параметров форм с параметрами методов действий в MVC Framework значительно упрощается с помощью встроенного средства DefaultModelBinder. Этот механизм может гибко настраиваться с помощью атрибута BindAttribute, который позволяет задавать списки допустимых и недопустимых для сопоставления свойств и, вдобавок к этому, переопределять префикс, используемый в представлении. Если же разработчику недостаточно функционала механизма Model Binding по умолчанию, он волен переопределить этот механизм своей реализацией и использовать его как глобально во всем приложении, так и определяя его для конкретного параметра определенного действия.

Советы по использованию контроллеров

Атрибуты ActionNameSelectorAttribute и ActionNameAttribute

В механизме MVC существует множество полезных функций. Одна из них — это атрибут ActionNameAttribute, являющийся реализацией атрибута ActionNameSelectorAttribute — механизма MVC Framework, который позволяет ограничить выбор методов класса контроллера при определении нужного.

Атрибут ActionNameSelectorAttribute содержит всего один метод IsValidName со следующим определением:

public abstract bool IsValidName(ControllerContext controllerContext,

                      string actionName, MethodInfo methodInfo);

При поиске необходимого для выполнения действия механизм MVC Framework, кроме всего прочего, проверит все действия на наличие атрибута, реализующего ActionNameSelectorAttribute. В случае, когда такой атрибут найден, у него вызывается метод IsValidName для проверки на соответствие действия требуемому имени.

Единственная реализация ActionNameSelectorAttribute, существующая в MVC Framework, — это атрибут ActionNameAttribute, который призван предоставить возможность создания псевдонимов для методов действий. Рассмотрим следующий фрагмент кода:

[ActionName("UserList")]

public ActionResult GetUserListFromCache()

Здесь методу GetuserListFromCache, который представляет собой действие контроллера, присваивается укороченный псевдоним userList. После этого в ответ на запрос действия UserList контроллером может быть вызван метод GetuserListFromCache.

Наследование контроллеров

При работе с контроллерами в MVC Framework полезной практикой является механизм наследования контроллеров. Так как контроллеры представляют собой классы, преимущества наследования контроллеров схожи с преимуществами наследования классов в C#. Основным таким преимуществом является возможность создания базового набора правил для некоторого количества контроллеров. Для этого в MVC Framework можно определить контроллер, который будет называться базовым, и наследовать все остальные контроллеры от него.

30
{"b":"971383","o":1}