MVC中将视图也打包成资源随程序集一起发布

利用asp.net MVC的扩展性,我们可以重新定义视图引擎,将视图文件*.cshtml也一并打包到程序集中。

这样可以提高基于MVC框架的程序集的独立性,简化部署难度。

 

首选重新定义一个视图引擎:

源码如下:

namespace Helpers
{
    /// <summary>
    /// 对标准的RazorViewEngine扩展,以使得视图引擎能找到程序集中打包的资源作为视图
    /// </summary>
    public class ResViewEngine : RazorViewEngine
    {
        /// <summary>
        /// 资源可能在的命名空间集合
        /// </summary>
        [Inject]
        public string[] ResNamespaces { get; set; }
        private static string rootPath = System.Web.Hosting.HostingEnvironment.MapPath("~");

        private string[] _startWiths = { "~/Views/", "~/Areas/" };
        private string logFile = Path.Combine(rootPath, "App_Data", "ResViews.txt");
        public ResViewEngine()
        {
            //删除以前写过的文件
            if (File.Exists(logFile))
            {
                string[] fileNameStrs = File.ReadAllText(logFile).Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

                foreach (string fn in fileNameStrs)
                {
                    if (File.Exists(fn))
                        File.Delete(fn);
                }
                File.Delete(logFile);
            }
        }

        protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
        {
            if (base.FileExists(controllerContext, virtualPath))
            {
                return true;
            }
            if (ResNamespaces == null) return false;

            foreach (string startWith in _startWiths)
            {
                if (!virtualPath.StartsWith(startWith)) continue;
                string tail = virtualPath.Substring(startWith.Length);
                tail = tail.Replace("/", ".");
                Stream stream = null;
                foreach (string ns in ResNamespaces)
                {
                    string nst = ns.Replace(".Controllers", "");
                    string resName = nst + startWith.Replace("/", ".").Replace("~", "") + tail;
                    stream = Assembly.Load(nst).GetManifestResourceStream(resName);
                    if (stream != null) break;
                }
                if (stream == null) return false;
                string path = controllerContext.HttpContext.Server.MapPath(virtualPath);
                IOHelper.WriteStreamToFile(stream, path);

                //将写过的文件路径名记入一个文本文件
                File.AppendAllText(logFile, path + Environment.NewLine);
            }
            return base.FileExists(controllerContext, virtualPath);
        }
    }
}

 当然,有一些帮助类需要自行补充。

 

还需要在global.asax.cs中将上述的视图引擎取代原有的:

        protected virtual void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            //......

            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new ResViewEngine());
        }

 最后,将需要打包的视图在VS2013中,按F4进入属性窗口,生成操作,选择”嵌入的资源“

posted @ 2015-09-08 13:36  黑白天使  阅读(223)  评论(0编辑  收藏  举报