2011-07-11 68 views
2

此代码为什么返回“不支持指定的方法”。为什么此代码返回“不支持指定的方法”。

using System; 
using System.IO; 
using System.Security.Cryptography; 
using System.Web.Mvc; 

public class ETagAttribute : ActionFilterAttribute 
{ 
    private string GetToken(Stream stream) { 
     MD5 md5 = MD5.Create(); 
     byte [] checksum = md5.ComputeHash(stream); 
     return Convert.ToBase64String(checksum, 0, checksum.Length); 
    } 

    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     filterContext.HttpContext.Response.AppendHeader("ETag", GetToken(filterContext.HttpContext.Response.OutputStream)); 
     base.OnResultExecuted(filterContext); 
    } 
} 

这应该工作,但是不。

显然微软取消了System.Web.HttpResponseStream.Read(Byte []缓冲区,Int32偏移量,Int32计数),以便它返回“不支持指定的方法”,不知道为什么他们会这么做,因为它继承对于System.IO.Stream基类...

堆栈跟踪

[NotSupportedException: Specified method is not supported.] 
    System.Web.HttpResponseStream.Read(Byte[] buffer, Int32 offset, Int32 count) +29 
    ETagAttribute.ReadFully(Stream input) in Filters\ETagAttribute.cs:11 
    ETagAttribute.GetToken(Stream stream) in Filters\ETagAttribute.cs:22 
    ETagAttribute.OnResultExecuted(ResultExecutedContext filterContext) in Filters\ETagAttribute.cs:29 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +282 
    System.Web.Mvc.<>c__DisplayClass1e.<InvokeActionResultWithFilters>b__1b() +19 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +260 
    System.Web.Mvc.<>c__DisplayClass1e.<InvokeActionResultWithFilters>b__1b() +19 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +177 
    System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343 
    System.Web.Mvc.Controller.ExecuteCore() +116 
    System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97 
    System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10 
    System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37 
    System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21 
    System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12 
    System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62 
    System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50 
    System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7 
    System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22 
    System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60 
    System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9 
    System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8920029 
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184 

回答

3

HttpResponse.OutputStream是为来,不阅读。这是一个只写流,基本上 - 就像Output属性返回一个TextWriter

+1

我如何读取输出流呢? –

+0

@肖恩:说实话,我不知道。您可能需要查看OutputCacheAttribute的来源以查看是否有帮助。 –

+0

您无法读取此输出流,它将流式传输到客户端。这就像站在公共汽车的外面,当公共汽车开着询问它的行进方向时,你现在实际上不会问现在,因为它在运动。 –

1

多大的战斗力后,我发现使用Response.Filter

using System; 
using System.IO; 
using System.Security.Cryptography; 
using System.Web; 
using System.Web.Mvc; 

public class ETagAttribute : ActionFilterAttribute { 
    public override void OnActionExecuting(ActionExecutingContext filterContext) { 
     try { 
      filterContext.HttpContext.Response.Filter = new ETagFilter(filterContext.HttpContext.Response); 
     } catch (System.Exception) { 
      // Do Nothing 
     }; 
    } 
} 

public class ETagFilter : MemoryStream { 
    private HttpResponseBase o = null; 
    private Stream filter = null; 

    public ETagFilter (HttpResponseBase response) { 
     o = response; 
     filter = response.Filter; 
    } 

    private string GetToken(Stream stream) { 
     byte[] checksum = new byte[0]; 
     checksum = MD5.Create().ComputeHash(stream); 
     return Convert.ToBase64String(checksum, 0, checksum.Length); 
    } 

    public override void Write(byte[] buffer, int offset, int count) { 
     byte[] data = new byte[count]; 
     Buffer.BlockCopy(buffer, offset, data, 0, count); 
     filter.Write(data, 0, count); 
     o.AddHeader("ETag", GetToken(new MemoryStream(data))); 
    } 
} 

资源的解决方案:

http://authors.aspalliance.com/aspxtreme/sys/Web/HttpResponseClassFilter.aspx
http://forums.asp.net/t/1380989.aspx/1

相关问题