Автоматическое связывание свойства модели, если оно присутствует - PullRequest
0 голосов
/ 03 марта 2012

Я не уверен, что знаю точную терминологию для того, что я хочу сделать, поэтому я просто опишу, что я хочу, и, надеюсь, кто-то даст мне ответ или направит меня в нужное место ...

Я хочу, чтобы некоторые (возможно, все) модели на моем сайте унаследовали от IGeneralSettings -

public interface IGeneralSettings
{
    User CurrentUser { get; set; }
    UserSettings PersonalSettings { get; set; }
}

и если текущий пользователь аутентифицирован / зарегистрирован, я проверю, относится ли модель текущего контроллера к типу, который реализует IGeneralSettings, и если это так, я заполню данные текущими данными пользователя.

Я использую Виндзорский замок в качестве контейнера IoC.
Я не хочу использовать сумку для этого.
Я не хочу вызывать метод, который будет делать это в каждом действии на каждом контроллере, я хочу, чтобы это автоматически вводилось при каждом запросе - это значит, что этот код будет написан один раз.

Возможно ли это?

Ответы [ 2 ]

3 голосов
/ 03 марта 2012

Я бы порекомендовал добавить ваши объекты CurrentUser и PersonalSettings в базовый контроллер и заполнять его каждый запрос (если они аутентифицированы).Затем вы можете получить к ним доступ в привязке пользовательской модели, поскольку у вас есть доступ к контексту контроллера.

Пример одного способа сделать это:

Базовый контроллер, который ваши контроллеры наследуют

public class BaseController : Controller
{
    public BaseController()
    {
        //You can load the CurrentUser and Settings here
        CurrentUser = new User
        {
            Id = 1
        };

        PersonalSettings = new UserSettings
        {
            Id = 1
        };
    }

    public User CurrentUser { get; set; }
    public UserSettings PersonalSettings { get; set; }
}

ModelBinder

public class ThingModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext,
                                ModelBindingContext bindingContext)
      {
        var model = (Thing)base.BindModel(controllerContext, bindingContext);

        var baseController = controllerContext.Controller as BaseController;
        if (baseController != null)
        {
            model.CurrentUser = baseController.CurrentUser;
            model.PersonalSettings = baseController.PersonalSettings;
        }

        return model;
      }
}

Добавить ModelBinder в Application_Start of Global.asax

ModelBinders.Binders.Add(typeof(Thing), new ThingModelBinder());

Контроллер

public class HomeController : BaseController
{
    [HttpPost]
    public ActionResult Save(Thing model)
    {
        //model has CurrentUser and PersonalSettings set 
        //without any values being posted. 
        //You can also access the values on the BaseController 
        //if you don't want to automatically bind it.

        return View();
    }
}
0 голосов
/ 03 марта 2012

Другой способ, который я нашел в моем последнем проекте: Определите метод расширения для Controller, например:

public static Models.User GetUser(this Controller controller)
    {
        string name = controller.User.Identity.Name;
        string alias = name.Substring(name.LastIndexOf('\\') + 1);
        string domain = name.Substring(0, name.IndexOf('\\') - 1);
        User user = User.ByAlias(alias);
        if (user == null)
        {
            user = new User();
            user.Name = controller.User.Identity.Name;
            user.Alias = alias;
            user.Domain = domain;
            user.Description = "Automatically registered";

            Guid userId = Models.User.Create(user, Guid.Empty);
            user = User.ByAlias(alias);
        }
        return user;
    }

Это не нарушило бы вашу текущую структуру класса.

...