自定义 ViewEngine ASP.NET MVC 3

发布于 2024-11-07 10:10:18 字数 129 浏览 0 评论 0原文

我正在为 ASP.NET MVC 的自定义视图引擎寻找最简单的解决方案。这样我就可以超越路径来寻找视图。

实际上,我正在尝试在我的解决方案中构建一个主题系统。我查看了网络,但发现了很难学习和实施的解决方案。

谢谢

I am looking for the simplest solution for the custom viewengine for asp.net mvc. So I can over-ride the path to look for the views.

Actually, I am trying to build a theme system in my solution. I looked over web but found solution which is hard to learn and implement.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

东走西顾 2024-11-14 10:10:18

这就是我用的。它在主题文件夹中查找视图。在构造函数的第一行设置主题名称。它还支持移动视图,但您需要 51 Degrees Mobi 之类的工具来为您提供移动浏览器详细信息。

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;

namespace Milkshake.Commerce.MvcClient.ViewEngines
{
    /// <summary>
    /// Milkshake Commerce specific ViewEngine.
    /// </summary>
    public class MilkshakeViewEngine : WebFormViewEngine
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="MilkshakeViewEngine"/> class.
        /// </summary>
        public MilkshakeViewEngine()
        {
            string themeName = AppData.ThemeName;

            var masterLocationFormats = new List<string>();
            masterLocationFormats.Add("~/Views/Themes/" + themeName + "/{0}.master");
            masterLocationFormats.AddRange(MasterLocationFormats);

            MasterLocationFormats = masterLocationFormats.ToArray();

            var partialViewLocationFormats = new List<string>();
            partialViewLocationFormats.Add("~/Views/Themes/" + themeName + "/{1}/{0}.aspx");
            partialViewLocationFormats.Add("~/Views/Themes/" + themeName + "/{1}/{0}.ascx");
            partialViewLocationFormats.Add("~/Views/Themes/" + themeName + "/{0}.aspx");
            partialViewLocationFormats.Add("~/Views/Themes/" + themeName + "/{0}.ascx");
            partialViewLocationFormats.AddRange(PartialViewLocationFormats);

            PartialViewLocationFormats = partialViewLocationFormats.ToArray();

            var viewLocationFormats = new List<string>();
            viewLocationFormats.Add("~/Views/Themes/" + themeName + "/{1}/{0}.aspx");
            viewLocationFormats.Add("~/Views/Themes/" + themeName + "/{1}/{0}.ascx");
            viewLocationFormats.Add("~/Views/Themes/" + themeName + "/{0}.aspx");
            viewLocationFormats.Add("~/Views/Themes/" + themeName + "/{0}.ascx");
            viewLocationFormats.AddRange(ViewLocationFormats);

            ViewLocationFormats = viewLocationFormats.ToArray();
        }

        /// <summary>
        /// Gets the user-selected <see cref="UserExperiences"/> setting, or returns the defualt if no experience has been selected.
        /// </summary>
        /// <returns>Returns the user experience selected by the user.</returns>
        public static UserExperiences GetUserExperienceSelected()
        {
            HttpContext context = HttpContext.Current;
            UserExperiences userExperience = context.Request.Browser.IsMobileDevice ? UserExperiences.Mobile : UserExperiences.Desktop;
            var userExperienceCookie = context.Request.Cookies["UserExperience"];

            if (userExperienceCookie != null)
            {
                if (!String.IsNullOrWhiteSpace(userExperienceCookie.Value))
                {
                    Enum.TryParse<UserExperiences>(userExperienceCookie.Value, out userExperience);
                }
            }
            else
            {
                SetUserExperience(userExperience);
            }

            return userExperience;
        }

        /// <summary>
        /// Sets the user experience cookie.
        /// </summary>
        /// <param name="experience">The user experience.</param>
        public static void SetUserExperience(UserExperiences experience)
        {
            HttpContext context = HttpContext.Current;
            HttpCookie userExperienceCookie = context.Request.Cookies["UserExperience"];

            if (userExperienceCookie == null)
            {
                userExperienceCookie = new HttpCookie("UserExperience");
            }

            userExperienceCookie.Value = experience.ToString();
            userExperienceCookie.Path = "/";
            userExperienceCookie.Expires = DateTime.UtcNow.AddDays(30);

            context.Response.Cookies.Add(userExperienceCookie);
        }

        /// <summary>
        /// Finds the specified view by using the specified controller context and master view name.
        /// </summary>
        /// <remarks>This override is used to determine if the browser is a mobile phone.
        /// If so, and it is supported, we add the phone specific folder/view name to the existing viewname,
        /// which forces the ViewManager to find a Theme specific mobile view (specific for that phone), or just use the built in mobile view.</remarks>
        /// <param name="controllerContext">The controller context.</param>
        /// <param name="viewName">The name of the view.</param>
        /// <param name="masterName">The name of the master view.</param>
        /// <param name="useCache">true to use the cached view.</param>
        /// <returns>The page view.</returns>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="controllerContext"/> parameter is null (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentException">The <paramref name="viewName"/> parameter is null or empty.</exception>
        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            ViewEngineResult result = null;
            var request = controllerContext.HttpContext.Request;
            var userExperience = GetUserExperienceSelected();

            // Avoid unnecessary checks if this device isn't suspected to be a mobile device
            if (userExperience == UserExperiences.Mobile)
            {
                masterName = "Mobile/Mobile";
                result = base.FindView(controllerContext, "Mobile/" + viewName, masterName, useCache);
            }

            // Fall back to desktop view if no other view has been selected
            if (result == null || result.View == null)
            {
                result = base.FindView(controllerContext, viewName, masterName, useCache);
            }

            return result;
        }

        /// <summary>
        /// Adds the default mobile location formats.
        /// </summary>
        /// <param name="defaultLocationFormats">The default location formats.</param>
        /// <param name="viewLocationFormats">The view location formats.</param>
        private void AddDefaultMobileLocationFormats(string[] defaultLocationFormats, List<string> viewLocationFormats)
        {
            var mobileViewLocationFormats = new List<string>();

            foreach (var item in defaultLocationFormats)
            {
                if (item.Contains("Views/{1}/{0}"))
                {
                    mobileViewLocationFormats.Add(item.Replace("/{1}/{0}", "/{1}/Mobile/{0}"));
                }
                else if (item.Contains("Views/Shared/{0}"))
                {
                    mobileViewLocationFormats.Add(item.Replace("/Shared/{0}", "/Shared/Mobile/{0}"));
                }
            }

            viewLocationFormats.AddRange(mobileViewLocationFormats);
        }
    }
}

This is what I use. It looks for views in a theme folder. Set the theme name, in the first line of the constructor. It also supports mobile views, but you'll need something like 51 Degrees Mobi to provide you with the mobile browser details.

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;

namespace Milkshake.Commerce.MvcClient.ViewEngines
{
    /// <summary>
    /// Milkshake Commerce specific ViewEngine.
    /// </summary>
    public class MilkshakeViewEngine : WebFormViewEngine
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="MilkshakeViewEngine"/> class.
        /// </summary>
        public MilkshakeViewEngine()
        {
            string themeName = AppData.ThemeName;

            var masterLocationFormats = new List<string>();
            masterLocationFormats.Add("~/Views/Themes/" + themeName + "/{0}.master");
            masterLocationFormats.AddRange(MasterLocationFormats);

            MasterLocationFormats = masterLocationFormats.ToArray();

            var partialViewLocationFormats = new List<string>();
            partialViewLocationFormats.Add("~/Views/Themes/" + themeName + "/{1}/{0}.aspx");
            partialViewLocationFormats.Add("~/Views/Themes/" + themeName + "/{1}/{0}.ascx");
            partialViewLocationFormats.Add("~/Views/Themes/" + themeName + "/{0}.aspx");
            partialViewLocationFormats.Add("~/Views/Themes/" + themeName + "/{0}.ascx");
            partialViewLocationFormats.AddRange(PartialViewLocationFormats);

            PartialViewLocationFormats = partialViewLocationFormats.ToArray();

            var viewLocationFormats = new List<string>();
            viewLocationFormats.Add("~/Views/Themes/" + themeName + "/{1}/{0}.aspx");
            viewLocationFormats.Add("~/Views/Themes/" + themeName + "/{1}/{0}.ascx");
            viewLocationFormats.Add("~/Views/Themes/" + themeName + "/{0}.aspx");
            viewLocationFormats.Add("~/Views/Themes/" + themeName + "/{0}.ascx");
            viewLocationFormats.AddRange(ViewLocationFormats);

            ViewLocationFormats = viewLocationFormats.ToArray();
        }

        /// <summary>
        /// Gets the user-selected <see cref="UserExperiences"/> setting, or returns the defualt if no experience has been selected.
        /// </summary>
        /// <returns>Returns the user experience selected by the user.</returns>
        public static UserExperiences GetUserExperienceSelected()
        {
            HttpContext context = HttpContext.Current;
            UserExperiences userExperience = context.Request.Browser.IsMobileDevice ? UserExperiences.Mobile : UserExperiences.Desktop;
            var userExperienceCookie = context.Request.Cookies["UserExperience"];

            if (userExperienceCookie != null)
            {
                if (!String.IsNullOrWhiteSpace(userExperienceCookie.Value))
                {
                    Enum.TryParse<UserExperiences>(userExperienceCookie.Value, out userExperience);
                }
            }
            else
            {
                SetUserExperience(userExperience);
            }

            return userExperience;
        }

        /// <summary>
        /// Sets the user experience cookie.
        /// </summary>
        /// <param name="experience">The user experience.</param>
        public static void SetUserExperience(UserExperiences experience)
        {
            HttpContext context = HttpContext.Current;
            HttpCookie userExperienceCookie = context.Request.Cookies["UserExperience"];

            if (userExperienceCookie == null)
            {
                userExperienceCookie = new HttpCookie("UserExperience");
            }

            userExperienceCookie.Value = experience.ToString();
            userExperienceCookie.Path = "/";
            userExperienceCookie.Expires = DateTime.UtcNow.AddDays(30);

            context.Response.Cookies.Add(userExperienceCookie);
        }

        /// <summary>
        /// Finds the specified view by using the specified controller context and master view name.
        /// </summary>
        /// <remarks>This override is used to determine if the browser is a mobile phone.
        /// If so, and it is supported, we add the phone specific folder/view name to the existing viewname,
        /// which forces the ViewManager to find a Theme specific mobile view (specific for that phone), or just use the built in mobile view.</remarks>
        /// <param name="controllerContext">The controller context.</param>
        /// <param name="viewName">The name of the view.</param>
        /// <param name="masterName">The name of the master view.</param>
        /// <param name="useCache">true to use the cached view.</param>
        /// <returns>The page view.</returns>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="controllerContext"/> parameter is null (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentException">The <paramref name="viewName"/> parameter is null or empty.</exception>
        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            ViewEngineResult result = null;
            var request = controllerContext.HttpContext.Request;
            var userExperience = GetUserExperienceSelected();

            // Avoid unnecessary checks if this device isn't suspected to be a mobile device
            if (userExperience == UserExperiences.Mobile)
            {
                masterName = "Mobile/Mobile";
                result = base.FindView(controllerContext, "Mobile/" + viewName, masterName, useCache);
            }

            // Fall back to desktop view if no other view has been selected
            if (result == null || result.View == null)
            {
                result = base.FindView(controllerContext, viewName, masterName, useCache);
            }

            return result;
        }

        /// <summary>
        /// Adds the default mobile location formats.
        /// </summary>
        /// <param name="defaultLocationFormats">The default location formats.</param>
        /// <param name="viewLocationFormats">The view location formats.</param>
        private void AddDefaultMobileLocationFormats(string[] defaultLocationFormats, List<string> viewLocationFormats)
        {
            var mobileViewLocationFormats = new List<string>();

            foreach (var item in defaultLocationFormats)
            {
                if (item.Contains("Views/{1}/{0}"))
                {
                    mobileViewLocationFormats.Add(item.Replace("/{1}/{0}", "/{1}/Mobile/{0}"));
                }
                else if (item.Contains("Views/Shared/{0}"))
                {
                    mobileViewLocationFormats.Add(item.Replace("/Shared/{0}", "/Shared/Mobile/{0}"));
                }
            }

            viewLocationFormats.AddRange(mobileViewLocationFormats);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文