Asp.net 在没有服务器的情况下关闭ETag

Asp.net 在没有服务器的情况下关闭ETag,asp.net,apache,asp.net-mvc-4,etag,yslow,Asp.net,Apache,Asp.net Mvc 4,Etag,Yslow,你好,, 我刚开始学习ASP.NET MVC 4,我在一家公司实习,他告诉我在没有服务器的情况下创建一个基本的webshop,然后用YSlow验证HTML和网站速度 我一直很忙,当我完成网店时,我开始使用YSlow将速度应用到网站上,但有一件事我似乎无法解决,那就是配置错误的ETag: “有5个组件配置错误的ETag”根据下面的评论,这是一个练习,显然PC不会有很好的性能。您可以使用httpHandler。这里有一个我用于图像,它将有助于您的yslow(但请注意,这并不能保证性能,而是用于指导非

你好,, 我刚开始学习ASP.NET MVC 4,我在一家公司实习,他告诉我在没有服务器的情况下创建一个基本的webshop,然后用YSlow验证HTML和网站速度

我一直很忙,当我完成网店时,我开始使用YSlow将速度应用到网站上,但有一件事我似乎无法解决,那就是配置错误的ETag

“有5个组件配置错误的ETag”根据下面的评论,这是一个练习,显然PC不会有很好的性能。您可以使用httpHandler。这里有一个我用于图像,它将有助于您的yslow(但请注意,这并不能保证性能,而是用于指导非常繁忙的站点)

公共类ImageHandler:IHttpHandler
{
公共void ProcessRequest(HttpContext上下文)
{
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetMaxAge(新的时间跨度(28,0,0,0));
//将上次修改日期设置为程序集的创建数据
Assembly thisAssembly=Assembly.getExecutionGassembly();
字符串thisPath=thissembly.CodeBase.Replace(@“file:///”,“”);
string assemblyName=“yoursassembly”;
字符串assemblyPath=thisPath.Replace(thisAssembly.ManifestModule.ScopeName,assemblyName);
var assemblyInfo=新文件信息(assemblyPath);
var creationDate=assemblyInfo.CreationTime;
字符串eTag=GetFileETag(assemblyPath,creationDate);
//设置缓存信息
context.Response.Cache.SetCacheability(HttpCacheability.Private);
context.Response.Cache.VaryByHeaders[“如果自”]=true修改;
context.Response.Cache.VaryByHeaders[“如果没有匹配”]=true;
context.Response.Cache.SetLastModified(creationDate);
context.Response.Cache.SetETag(eTag);
if(IsFileModified(assemblyPath、creationDate、eTag、context.Request))
{
//context.Response.ContentType=;
//在这里进行资源处理
context.Response.TransmitFile(context.Request.PhysicalPath);
}
其他的
{
//文件未更改,因此返回HTTP 304而不检索数据
context.Response.StatusCode=304;
context.Response.StatusDescription=“未修改”;
//显式设置内容长度标头,以便客户端不等待
//内容,但保持连接对其他请求开放
context.Response.AddHeader(“内容长度”,“0”);
}
context.Response.End();
}
公共布尔可重用
{
获取{return false;}
}
/// 
///检查是否已根据创建日期修改资源程序集。
/// 
/// 
/// 
/// 
private bool IsFileModified(字符串文件名、日期时间modifyDate、字符串eTag、HttpRequest请求)
{
//假设文件已被修改,除非我们可以确定其他情况
bool FileDateModified=true;
日期时间修改自;
TimeSpan ModifyDiff;
布尔·埃塔格切德;
//检查自请求标头以来是否已修改(如果存在)
字符串ifModifiedSince=request.Headers[“如果自”]起修改”;
如果(!string.IsNullOrEmpty(ifModifiedSince)和&ifModifiedSince.Length>0和&DateTime.TryParse(ifModifiedSince,out ModifiedSince))
{
FileDateModified=false;
如果(modifyDate>ModifiedSince)
{
ModifyDiff=modifyDate-ModifiedSince;
//忽略长达1秒的时间差,以补偿日期编码
FileDateModified=ModifyDiff>TimeSpan.FromSeconds(1);
}
}
//检查If None Match标头(如果存在)。FireFox使用该标头根据ETag响应标头验证实体
ETagChanged=false;
字符串ifNoneMatch=request.Headers[“如果不匹配”];
如果(!string.IsNullOrEmpty(ifNoneMatch)&&ifNoneMatch.Length>0)
{
ETagChanged=ifNoneMatch!=eTag;
}
返回ETagChanged | | FileDateModified;
}
/// 
///根据文件名和创建日期生成缓存ETag。
/// 
/// 
/// 
/// 
私有字符串GetFileETag(字符串文件名,日期时间修改日期)
{
字符串文件字符串;
编码器;
int字节数;
字节[]字符串字节;
//使用文件名和修改日期作为唯一标识符
fileString=fileName+modifyDate.ToString();
//获取字符串字节
stringEncoder=Encoding.UTF8.GetEncoder();
byteCount=stringEncoder.GetByteCount(fileString.ToCharray(),0,fileString.Length,true);
stringBytes=新字节[字节计数];
GetBytes(fileString.tocharray(),0,fileString.Length,stringBytes,0,true);
//{使用MD5的哈希字符串并返回十六进制编码的哈希}
MD5 Enc=MD5CryptoServiceProvider.Create();
返回“\”+BitConverter.ToString(Enc.ComputeHash(stringBytes))。替换(“-”,string.Empty)+“\”;
}
}
}
然后在配置中指定处理程序(如果不使用iis7,也在httphandlers下执行)


根据下面的评论,这是一个练习,显然PC的性能不会很好。您可以使用httpHandler。这里有一个我用于图像,它将有助于您的yslow(但请注意,这并不能保证性能,而是用于指导非常繁忙的站点)


public class ImageHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            context.Response.Cache.SetCacheability(HttpCacheability.Public);
            context.Response.Cache.SetMaxAge(new TimeSpan(28, 0, 0, 0, 0));

            // Setting the last modified date to the creation data of the assembly
        Assembly thisAssembly = Assembly.GetExecutingAssembly();
        string thisPath = thisAssembly.CodeBase.Replace(@"file:///", "");
        string assemblyName = "yourAssembly";
        string assemblyPath = thisPath.Replace(thisAssembly.ManifestModule.ScopeName, assemblyName);

        var assemblyInfo = new FileInfo(assemblyPath);
        var creationDate = assemblyInfo.CreationTime;
        string eTag = GetFileETag(assemblyPath, creationDate);      
        // set cache info
        context.Response.Cache.SetCacheability(HttpCacheability.Private);
        context.Response.Cache.VaryByHeaders["If-Modified-Since"] = true;
        context.Response.Cache.VaryByHeaders["If-None-Match"] = true;
        context.Response.Cache.SetLastModified(creationDate);
        context.Response.Cache.SetETag(eTag);
if (IsFileModified(assemblyPath, creationDate, eTag, context.Request))
        {
            //context.Response.ContentType = <specify content type>;
            // Do resource processing here
            context.Response.TransmitFile(context.Request.PhysicalPath);
        }
        else
        {
            // File hasn't changed, so return HTTP 304 without retrieving the data 
            context.Response.StatusCode = 304;
            context.Response.StatusDescription = "Not Modified";

            // Explicitly set the Content-Length header so the client doesn't wait for
            //  content but keeps the connection open for other requests 
            context.Response.AddHeader("Content-Length", "0");         
        }


        context.Response.End();


        }


        public bool IsReusable
        {
            get { return false; }
        }


        /// <summary>
        /// Checks if the resource assembly has been modified based on creation date.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <seealso cref="GetFileETag"/>
        private bool IsFileModified(string fileName, DateTime modifyDate, string eTag, HttpRequest request)
        {
            // Assume file has been modified unless we can determine otherwise 
            bool FileDateModified = true;
            DateTime ModifiedSince;
            TimeSpan ModifyDiff;
            bool ETagChanged;

            // Check If-Modified-Since request header, if it exists 
            string ifModifiedSince = request.Headers["If-Modified-Since"];
            if (!string.IsNullOrEmpty(ifModifiedSince) && ifModifiedSince.Length > 0 && DateTime.TryParse(ifModifiedSince, out ModifiedSince))
            {
                FileDateModified = false;
                if (modifyDate > ModifiedSince)
                {
                    ModifyDiff = modifyDate - ModifiedSince;
                    // Ignore time difference of up to one seconds to compensate for date encoding
                    FileDateModified = ModifyDiff > TimeSpan.FromSeconds(1);
                }
            }
            // Check the If-None-Match header, if it exists. This header is used by FireFox to validate entities based on the ETag response header 
            ETagChanged = false;
            string ifNoneMatch = request.Headers["If-None-Match"];
            if (!string.IsNullOrEmpty(ifNoneMatch) && ifNoneMatch.Length > 0)
            {
                ETagChanged = ifNoneMatch != eTag;
            }
            return ETagChanged || FileDateModified;
        }

        /// <summary>
        /// Generates a caching ETag based on file name and creation date.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <seealso cref="GetFileETag"/>
        private string GetFileETag(string fileName, DateTime modifyDate)
        {
            string fileString;
            Encoder stringEncoder;
            int byteCount;
            Byte[] stringBytes;

            // Use file name and modify date as the unique identifier 
            fileString = fileName + modifyDate.ToString();

            // Get string bytes 
            stringEncoder = Encoding.UTF8.GetEncoder();
            byteCount = stringEncoder.GetByteCount(fileString.ToCharArray(), 0, fileString.Length, true);
            stringBytes = new Byte[byteCount];

            stringEncoder.GetBytes(fileString.ToCharArray(), 0, fileString.Length, stringBytes, 0, true);

            //{ Hash string using MD5 and return the hex-encoded hash }
            MD5 Enc = MD5CryptoServiceProvider.Create();
            return "\"" + BitConverter.ToString(Enc.ComputeHash(stringBytes)).Replace("-", string.Empty) + "\"";

        }
    }
}
  <add name="pngs" verb="*" path="*.png" type="yourAssembly.HttpHandlers.ImageHandler, hcs.web" preCondition="managedHandler" />
  <add name="jpgs" verb="*" path="*.jpg" type="yourAssembly.HttpHandlers.ImageHandler, hcs.web" preCondition="managedHandler" />
  <add name="gif" verb="*" path="*.gif" type="yourAssembly.HttpHandlers.ImageHandler, hcs.web" preCondition="managedHandler" />