📜  处的视图必须派生自 WebViewPage 或 WebViewPage<TModel> . (1)

📅  最后修改于: 2023-12-03 14:51:39.099000             🧑  作者: Mango

WebViewPage 和 WebViewPage

在 ASP.NET MVC 中,视图是用来呈现模型数据的,而 ViewBag 和 ViewData 则是传递模型数据到视图的方式。为了使视图更加灵活有足够的控制权,MVC 提供了一个名为 WebViewPage 的类,这个类可以让我们在视图中使用 C# 语言并且访问模型数据。

WebViewPage 类

WebViewPage 类是一个基类,它实现了 IView 接口和 IViewDataContainer 接口,让我们可以在视图中使用 C# 代码和 ViewData 字典对象。这个类定义了一个叫做 Model 的属性,可以用来存储我们的模型数据。对于非泛型视图,这个属性被定义为 Object 类型。

public abstract class WebViewPage : System.Web.Mvc.WebViewPage
{
    public object Model { get; set; }
}

使用 WebViewPage 类的视图必须要指定它们的基类是 WebViewPage 类。这通常是通过在视图文件的 @inherits 指令来实现的:

@inherits System.Web.Mvc.WebViewPage

或者,您也可以在应用程序的全局.asax 文件中注册 WebViewPage 类,让 ASP.NET MVC 在渲染视图时自动使用它:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        // Register the WebViewPage base class for all views
        ViewEngines.Engines.Add(new RazorViewEngine
        {
            PartialViewLocationFormats = new[] { "~/Views/Partials/{0}.cshtml" },
            ViewLocationFormats = new[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" }
        });

        ViewEngines.Engines.Find(x => x.GetType() == typeof(RazorViewEngine)).GetType().GetProperty("AreaViewLocationFormats").SetValue(ViewEngines.Engines.Find(x => x.GetType() == typeof(RazorViewEngine)),new[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml", "~/Views/Shared/{0}.cshtml" });
        ViewEngines.Engines.Find(x => x.GetType() == typeof(RazorViewEngine)).GetType().GetProperty("AreaPartialViewLocationFormats").SetValue(ViewEngines.Engines.Find(x => x.GetType() == typeof(RazorViewEngine)), new[] { "~/Areas/{2}/Views/Partials/{0}.cshtml", "~/Views/Partials/{0}.cshtml" });
        ViewEngines.Engines.Find(x => x.GetType() == typeof(RazorViewEngine)).GetType().GetProperty("FileExtensions").SetValue(ViewEngines.Engines.Find(x => x.GetType() == typeof(RazorViewEngine)), new[] { "cshtml"});
    }
}
WebViewPage

WebViewPage 类继承了 WebViewPage 类,并添加了一个泛型参数 TModel,用来指定视图所使用的模型类型。在视图中,我们可以直接通过 Model 属性来访问使用泛型参数 TModel 的模型数据。

public abstract class WebViewPage<TModel> : WebViewPage
{
    public new TModel Model { get; set; }
}

如果我们的视图需要使用一个特定类型的模型,我们需要为视图指定泛型参数 TModel。这通常通过在视图文件的 @model 指令来实现:

@model IEnumerable<MyApp.Models.User>

或者,您也可以使用实现了 IViewEngine 接口的引擎来自动检测视图所使用的模型类型,并自动使用 WebViewPage 类:

public class MyViewEngine : RazorViewEngine
{
    public MyViewEngine()
    {
        AreaMasterLocationFormats = new[]
        {
            "~/Areas/{2}/Views/{1}/{0}.cshtml",
            "~/Areas/{2}/Views/Shared/{0}.cshtml",
            "~/Views/Shared/{0}.cshtml",
            "~/Areas/{2}/Views/Shared/{0}.vbhtml",
            "~/Views/Shared/{0}.vbhtml"
        };

        AreaViewLocationFormats = new[]
        {
            "~/Areas/{2}/Views/{1}/{0}.cshtml",
            "~/Areas/{2}/Views/{1}/{0}.vbhtml",
            "~/Areas/{2}/Views/Shared/{0}.cshtml",
            "~/Areas/{2}/Views/Shared/{0}.vbhtml",
            "~/Views/{1}/{0}.cshtml",
            "~/Views/{1}/{0}.vbhtml",
            "~/Views/Shared/{0}.cshtml",
            "~/Views/Shared/{0}.vbhtml"
        };

        AreaPartialViewLocationFormats = new[]
        {
            "~/Areas/{2}/Views/{1}/{0}.cshtml",
            "~/Areas/{2}/Views/{1}/{0}.vbhtml",
            "~/Areas/{2}/Views/Shared/{0}.cshtml",
            "~/Areas/{2}/Views/Shared/{0}.vbhtml",
            "~/Views/Shared/{0}.cshtml",
            "~/Views/Shared/{0}.vbhtml"
        };

        MasterLocationFormats = new[]
        {
            "~/Views/{1}/{0}.cshtml",
            "~/Views/{1}/{0}.vbhtml",
            "~/Views/Shared/{0}.cshtml",
            "~/Views/Shared/{0}.vbhtml"
        };

        ViewLocationFormats = new[]
        {
            "~/Views/{1}/{0}.cshtml",
            "~/Views/{1}/{0}.vbhtml",
            "~/Views/Shared/{0}.cshtml",
            "~/Views/Shared/{0}.vbhtml"
        };

        PartialViewLocationFormats = ViewLocationFormats;
    }

    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
    {
        var view = base.CreatePartialView(controllerContext, partialPath);

        return new RazorView(controllerContext, partialPath, null, false, new string[0]);
    }

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
    {
        var view = base.CreateView(controllerContext, viewPath, masterPath);

        return new RazorView(controllerContext, viewPath, masterPath, true, new string[0]);
    }
}
小结

WebViewPage 和 WebViewPage 类是 ASP.NET MVC 提供的视图基类,它们允许我们在视图中使用 C# 代码并访问视图数据。如果您的视图不需要使用特定类型的模型数据,您可以使用 WebViewPage 类,否则您需要使用 WebViewPage 类,并为视图指定泛型参数 TModel。