예제 #1
0
        /// <summary>
        /// 合并模板和数据字典,生成静态文件,同时放入缓存中。
        /// </summary>
        /// <param name="templateName">模板文件名称</param>
        /// <param name="dict">数据字典</param>
        /// <param name="absoluteFilePath">生成文件绝对路径(不包含物理路径)</param>
        /// <param name="isUseLocalCache">是否只使用本地缓存的方式存放静态文件</param>
        /// <returns>返回模板页面内容(去掉VM语法之后的结果),文件的内容</returns>
        private static string MergeAndGenerateFile(string templateName, Dictionary <string, object> dict, string absoluteFilePath, bool isUseLocalCache)
        {
            string fileContent = NVelocityBus.MergeVM(templateName, dict);

            if (!string.IsNullOrWhiteSpace(fileContent))
            {
                if (isUseLocalCache)
                {//如果页面设置生成静态页面,并且该页面单独设置只使用本地缓存存放静态页面(例如:google爬虫收录的页面,因为量很大并且很集中,不适合放在Redis缓存中。)(一级缓存)
                    UseLocalCache(absoluteFilePath, fileContent, true);
                }
                else
                {
                    //使用本地缓存存放数据(一级缓存)。
                    UseLocalCache(absoluteFilePath, fileContent, !NVelocityBus.CACHE_REDIS);
                    if (NVelocityBus.CACHE_REDIS)
                    {//如果页面设置生成静态页面,并且网站设置使用Redis缓存存放静态页面
                        try
                        {
                            //写入Redis缓存(二级缓存)。
                            //StackExchangeRedisBus.StringSet(absoluteFilePath, ZipHelper.GZipCompress(fileContent), TimeSpan.FromDays(NVelocityBus.CACHE_DAY));
                        }
                        catch (Exception)
                        {//写入Redis失败
                        }
                    }
                }
            }
            return(fileContent);
        }
예제 #2
0
        /// <summary>
        /// 生成静态文件
        /// </summary>
        /// <param name="absoluteFilePath">生成文件绝对路径(不包含物理路径)</param>
        /// <param name="fileContent">要保存的文件内容</param>
        /// <param name="fullFilePath">生成文件文件成功之后,返回文件的物理路径,返回null表示生成文件失败</param>
        private static void GenerateFile(string absoluteFilePath, string fileContent, out string fullFilePath)
        {
            fullFilePath = null;
            //文件名转码,防止URL参数当文件名过长.wangwei-2014-06-2
            absoluteFilePath = System.Web.HttpUtility.UrlDecode(absoluteFilePath);
            if (!string.IsNullOrEmpty(fileContent))
            {
                fullFilePath = NVelocityBus.GenerateFilePath(absoluteFilePath);
                bool   isGenerateFile       = true;
                char[] invalidFileNameChars = IOHelper.InvalidFileNameChars;
                string fileName             = IOHelper.GetFileNameWithoutExtension(fullFilePath);
                foreach (char invalidChar in invalidFileNameChars)
                {
                    if (fileName.Contains(new string(invalidChar, 1)))
                    {
                        isGenerateFile = false;
                        break;
                    }
                }
                fileName = null;

                if (isGenerateFile)
                {
                    char[] invalidPathChars = IOHelper.InvalidPathChars;
                    string filePath         = IOHelper.GetDirectoryName(fullFilePath);
                    foreach (char invalidChar in invalidPathChars)
                    {
                        if (filePath.Contains(new string(invalidChar, 1)))
                        {
                            isGenerateFile = false;
                            break;
                        }
                    }
                    filePath = null;
                }

                if (isGenerateFile)
                {
                    lock (@FileLockObject)
                    {
                        try
                        {
                            IOHelper.GenerateFile(fullFilePath, fileContent);
                        }
                        catch
                        {
                            fullFilePath = null;
                        }
                    }
                }
                else
                {
                    fullFilePath = null;
                }
            }
        }
예제 #3
0
        /// <summary>
        /// 使用本地缓存
        /// </summary>
        /// <param name="absoluteFilePath">生成文件的绝对路径</param>
        /// <param name="fileContent">文件内容</param>
        /// <param name="isGenerateFile">是否生成本地文件</param>
        private static void UseLocalCache(string absoluteFilePath, string fileContent, bool isGenerateFile)
        {
            string fullFilePath = null;

            if (isGenerateFile)
            {
                //如果需要生成本地静态文件
                NVelocityBus.GenerateFile(absoluteFilePath, fileContent, out fullFilePath);//生成静态文件
            }
            if (string.IsNullOrEmpty(fullFilePath))
            {
                //如果生成文件失败,也放进缓存中(一级缓存),但是放入缓存的时间设置为绝对过期时间。防止频繁请求服务器端占用更多的资源。
                DataCacheBus.Insert(absoluteFilePath, fileContent, DateTime.Now.AddMinutes(CACHE_DATETIME));
            }
            else
            {
                //如果生成文件成功,放入缓存并设置相对过期时间同时还加上缓存依赖。(一级缓存)
                DataCacheBus.Insert(absoluteFilePath, fileContent, TimeSpan.FromMinutes(CACHE_DATETIME), fullFilePath);
            }
        }
예제 #4
0
        /// <summary>
        /// 输出到客户端浏览器
        /// </summary>
        /// <param name="request"></param>
        /// <param name="response"></param>
        /// <param name="templateName">Velocity模板文件名称</param>
        /// <param name="dict">Velocity模板文件所用到的数据字典</param>
        /// <param name="isGenerateFile">是否生成静态文件</param>
        /// <param name="isUseLocalCache">是否只使用本地缓存的方式存放静态文件(例如:Google爬虫收录的页面,只需要在本地生成静态文件。)</param>
        public static void Print(HttpRequest request, HttpResponse response, string templateName, Dictionary <string, object> dict, bool isGenerateFile, bool isUseLocalCache)
        {
            string fileContent      = null;
            string absoluteFilePath = null;

            if (isGenerateFile)
            {
                absoluteFilePath = request.RequestContext.HttpContext.Items[NVelocityBus.NVELOCITY_TARGET_FILE_PATH] as string; //改从上下文对象里面获取,2015-11-17。
                //当设置生成静态页面时才会生成静态的文件。
                fileContent = NVelocityBus.MergeAndGenerateFile(templateName, dict, absoluteFilePath, isUseLocalCache);
            }
            else
            {
                //没有设置生成静态文件,并且不满足生成条件的,一律按动态页面处理。
                fileContent = NVelocityBus.MergeVM(templateName, dict);
            }
            if (!string.IsNullOrWhiteSpace(fileContent))
            {
                NVelocityBus.Output(request, response, fileContent, absoluteFilePath, isGenerateFile);
            }
        }
예제 #5
0
        public static void BeginRequest(HttpRequest request, HttpResponse response)
        {
            Uri filterUri      = GetUriWithoutTrace(request, response);
            int segmentsLength = filterUri.Segments.Length;

            if (string.IsNullOrWhiteSpace(IOHelper.GetFileExtension(segmentsLength > 0 ? filterUri.Segments[segmentsLength - 1] : filterUri.AbsolutePath)) &&
                string.IsNullOrWhiteSpace(filterUri.Query))
            {//如果页面URL不带"/"结尾,需要添加"/"然后执行301跳转。wangyunpeng.
                if (!string.IsNullOrWhiteSpace(filterUri.AbsolutePath) && !filterUri.AbsolutePath.EndsWith("/"))
                {
                    Uri        originalUri = request.Url;
                    UriBuilder uriBuilder  = new UriBuilder(originalUri.Scheme, originalUri.Host, originalUri.Port);
                    uriBuilder.Path  = string.Concat(originalUri.AbsolutePath, "/");
                    uriBuilder.Query = originalUri.Query;
                    string url301 = uriBuilder.ToString();
                    response.RedirectPermanent(url301, true);
                    return;
                }
            }
            string physicalPath     = request.PhysicalPath;                                                                              //指定的路径或文件名太长,文件名必须少于 260 个字符
            string absoluteFilePath = string.Concat(UrlHasher.Hash(filterUri, physicalPath, "/"), NVelocityBus.DEFAULT_DOCUMENT_SUFFIX); //所有url全部hash存放到redis和本地内存中去。区分URL大小写。wangyunpeng。2016-7-20。

            request.RequestContext.HttpContext.Items[NVelocityBus.NVELOCITY_TARGET_FILE_PATH] = absoluteFilePath;                        //设置放入上下文对象里面获取,2015-11-17。wangyunpeng
            //读取本地缓存(一级缓存)
            string fileContent = DataCacheBus.Get(absoluteFilePath) as string;

            //读取Redis缓存(二级缓存)
            if (NVelocityBus.CACHE_REDIS && string.IsNullOrWhiteSpace(fileContent))
            {
                try
                {
                    fileContent = "";//StackExchangeRedisBus.StringGet(absoluteFilePath);
                }
                catch (Exception)
                { }
                if (!string.IsNullOrWhiteSpace(fileContent))
                {//放进缓存中(一级缓存)
                    DataCacheBus.Insert(absoluteFilePath, fileContent = ZipHelper.GZipDeCompress(fileContent), DateTime.Now.AddMinutes(NVelocityBus.CACHE_DATETIME));
                }
            }
            //如果仅采用本地缓存策略,需要从磁盘上读取静态文件。(防止清除本地缓存后访问量过大,改从静态文件读取)
            if (!NVelocityBus.CACHE_REDIS && string.IsNullOrWhiteSpace(fileContent))
            {
                string physicalFilePath = null;
                string fileExtension    = IOHelper.GetFileExtension(absoluteFilePath);
                if (!string.IsNullOrWhiteSpace(fileExtension) && fileExtension.Equals(NVelocityBus.DEFAULT_DOCUMENT_SUFFIX, StringComparison.CurrentCultureIgnoreCase))
                {
                    physicalFilePath = NVelocityBus.GenerateFilePath(absoluteFilePath);
                    DateTime fileDateTime = IOHelper.GetFileMaxDateTime(physicalFilePath);
                    if (fileDateTime != DateTime.MinValue)
                    {     //如果静态文件存在
                        if (fileDateTime.AddDays(NVelocityBus.CACHE_DAY) > DateTime.Now)
                        { //只读CACHE_DAY天之内的静态文件.
                            fileContent = IOHelper.GetFileContent(physicalFilePath);
                        }
                        else
                        {    //超过CACHE_DAY天之外的静态文件会自动删除.
                            IOHelper.DeleteFile(physicalFilePath);
                        }
                    }
                }
                if (!string.IsNullOrWhiteSpace(fileContent) && !string.IsNullOrWhiteSpace(physicalFilePath))
                {                                                                                                                            //如果读取磁盘上的文件成功
                    DataCacheBus.Insert(absoluteFilePath, fileContent, TimeSpan.FromMinutes(NVelocityBus.CACHE_DATETIME), physicalFilePath); //放入本地缓存(一级缓存)
                }
            }
            if (!string.IsNullOrWhiteSpace(fileContent))
            {
                NVelocityBus.Output(request, response, fileContent, absoluteFilePath, true);
            }
            fileContent      = null;
            absoluteFilePath = null;
        }
예제 #6
0
        /// <summary>
        /// 将文件内容输出到客户端客户端浏览器,支持http头操作。
        /// </summary>
        /// <param name="request"></param>
        /// <param name="response"></param>
        /// <param name="fileContent">要往客户端浏览器输出的文本内容</param>
        /// <param name="isHttpHead">True表示使用http头操作,False表示不使用http头操作</param>
        internal static void Output(HttpRequest request, HttpResponse response, string fileContent, string absoluteFilePath, bool isHttpHead)
        {
            if (string.IsNullOrWhiteSpace(fileContent))
            {
                return;
            }
            //wangyunpeng 增加http头,把生成的路径输出出来,方便修改页面使用。
            if (absoluteFilePath != null)
            {
                response.AddHeader("X-Page-Hash", absoluteFilePath);
            }
            HttpCachePolicy cache = response.Cache;

            cache.SetOmitVaryStar(true);//http://www.cnblogs.com/dudu/archive/2011/11/03/outputcache_Bug_vary.html
//#if DEBUG
            //本地调试不使用浏览器缓存
            //cache.SetCacheability(HttpCacheability.NoCache);
            //cache.SetExpires(DateTime.UtcNow.AddYears(-1));
            //cache.SetMaxAge(TimeSpan.Zero);
            //cache.SetProxyMaxAge(TimeSpan.Zero);
            //cache.SetNoServerCaching();
            //cache.SetNoStore();
            //cache.SetNoTransforms();
//#else
            string ifModifiedSince = request.Headers["If-Modified-Since"];

            if (isHttpHead)
            {
                if (
                    !string.IsNullOrWhiteSpace(ifModifiedSince) &&
                    TimeSpan.FromTicks(DateTime.Now.Ticks - TypeParseHelper.StrToDateTime(ifModifiedSince).Ticks).Minutes < CACHE_DATETIME)
                {
                    response.StatusCode        = (int)System.Net.HttpStatusCode.NotModified;
                    response.StatusDescription = "Not Modified";
                    response.End();
                    return;
                }
                else
                {
                    cache.SetLastModifiedFromFileDependencies();
                    cache.SetETagFromFileDependencies();
                    cache.SetCacheability(HttpCacheability.Public);
                    cache.SetExpires(DateTime.UtcNow.AddMinutes(CACHE_DATETIME));
                    TimeSpan timeSpan = TimeSpan.FromMinutes(CACHE_DATETIME);
                    cache.SetMaxAge(timeSpan);
                    cache.SetProxyMaxAge(timeSpan);
                    cache.SetLastModified(DateTime.Now);
                    cache.SetValidUntilExpires(true);
                    cache.SetSlidingExpiration(true);
                }
            }

//#endif
            System.Text.Encoding encoding = IOHelper.GetHtmEncoding(fileContent) ?? NVelocityBus._GlobalizationSection.ResponseEncoding;
            response.ContentEncoding = encoding;
            response.ContentType     = response.ContentType;
            response.Write(fileContent);

            //压缩页面
            if (request.ServerVariables["HTTP_X_MICROSOFTAJAX"] == null)
            {
                if (NVelocityBus.IsAcceptEncoding(request, GZIP))
                {
                    response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
                    NVelocityBus.SetResponseEncoding(response, GZIP);
                }
                else if (NVelocityBus.IsAcceptEncoding(request, DEFLATE))
                {
                    response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
                    NVelocityBus.SetResponseEncoding(response, DEFLATE);
                }
            }
            //强制结束输出
            response.End();
        }