自动绑定模型属性(如果存在)

时间:2012-03-03 14:03:53

标签: c# asp.net-mvc castle-windsor

我不确定我知道我想要做什么的确切术语,所以我只是描述我想要的东西,希望有人会给我答案或指引我到正确的地方......

我希望我网站上的一些(可能是全部)模型继承自IGeneralSettings -

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

如果当前用户已通过身份验证/登录,我将检查当前控制器的模型是否为实现IGeneralSettings的类型,如果是,我将使用当前用户数据填充数据。

我使用Windsor Castle作为IoC容器 我不想使用这个属性包。
我不想在每个控制器的每个动作中调用一个会执行此操作的方法,我希望每次请求都自动注入 - 这意味着这段代码将被写入一次。

这可能吗?

2 个答案:

答案 0 :(得分:3)

我建议将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;
      }
}

在Global.asax的

的Application_Start中添加ModelBinder
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();
    }
}

答案 1 :(得分:0)

我在上一个项目中发现的另一种方式: 为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;
    }

这不会破坏你目前的班级结构。