ASP.NET MVC自动模型实例化(如果未提供模型)

本文关键字:模型 如果 实例化 NET MVC ASP | 更新日期: 2023-09-27 18:24:17

当视图模型没有给定时(当它们为null时),我试图实现视图模型的自动实例化。

控制器操作

public ActionResult SomeAction()
{
    return View("~/.../SomeView.cshtml"); //No model is given
}

SomeView.cshtml

@model Models.SomeModel //According to this type...
<h2>@Model.Title</h2>
//...auto instantiate @Model when it is null

我试图覆盖RazorViewEngine,但在ViewEngine时,我似乎(我可能错了)无法访问模型类型,它总是为null,即使提供了它。我应该能够学习null模型的类型,因为我们正在尝试实例化它,所以应该有另一个元数据,让我们获得视图的模型类型。

我尝试过扩展DefaultModelBinder,但它似乎只用于绑定Http请求中的模型,它在手动创建视图时没有启动。

我没主意了。我希望这样做是可行的。

ASP.NET MVC自动模型实例化(如果未提供模型)

在BorysG的帮助下,我们解决了这个问题,我还改进了它,以便与Partials合作。

讨论:http://forums.asp.net/t/1924332.aspx/1?ASP+NET+MVC+自动+模型+实例化+如果+模型+是+不是+提供

在此处复制代码:

public class CustomViewEngine : RazorViewEngine
{
    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
    {
        var view = base.CreatePartialView(controllerContext, partialPath);
        return new ViewWrapper(view);
    }
    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
    {
        var view = base.CreateView(controllerContext, viewPath, masterPath);
        return new ViewWrapper(view);
    }
}
public class ViewWrapper : IView
{
    protected IView View;
    public ViewWrapper(IView view)
    {
        View = view;
    }
    public void Render(ViewContext viewContext, TextWriter writer)
    {
        //Type modelType = BuildManager.GetCompiledType(razorView.ViewPath);
        var razorView = View as RazorView;
        if (razorView != null)
        {
            //if we could not get the model object - try to get it from what is declared in view
            var compiledViewType = BuildManager.GetCompiledType(razorView.ViewPath);
            var model = viewContext.ViewData.Model;
            Type baseType = compiledViewType.BaseType;
            //model is passed as generic parameter, like this MyView1 : WebViewPage<MyModel1>
            if (baseType != null && baseType.IsGenericType)
            {
                //and here the trick begins - extract type of model from generic arguments
                var modelType = baseType.GetGenericArguments()[0]; //the same as typeof(MyModel1)
                // ReSharper disable UseMethodIsInstanceOfType
                //If model is null, or model is not type of the given model (for partials)
                if (model == null || !modelType.IsAssignableFrom(model.GetType()))
                // ReSharper restore UseMethodIsInstanceOfType
                {
                    //Set @model and render the view
                    viewContext.ViewData.Model = Activator.CreateInstance(modelType);
                }
            }
        }
        View.Render(viewContext, writer);
    }
}

也可以在Application_Start()中输入Global.asax.cs。

//remove default Razor and WebForm view engines
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomViewEngine());
相关文章: