【问题标题】:Why does File.ReadAllBytes work on the IIS Server when System.IO.FileStream causes an Access Violation error当 System.IO.FileStream 导致访问冲突错误时,为什么 File.ReadAllBytes 在 IIS 服务器上工作
【发布时间】:2018-06-19 07:24:33
【问题描述】:

我有一个返回 pdf 的 REST 服务。当我使用 FileStream 时,我在 Visual Studio 中调试时收到了 pdf,但是当我将它部署到 IIS 7 时,我得到了拒绝访问

[HttpGet]
[Route("Document/Pdf/{id}")]
[ResponseType(typeof(HttpResponseMessage))]
public async Task<HttpResponseMessage> DocumentPdfGet(int id)
{
        string pdfPath = System.Web.HttpContext.Current.Server.MapPath("~/test.pdf");
        System.IO.FileStream stream = new FileStream(pdfPath, FileMode.Open);
        string filename = Path.GetFileName(pdfPath);

        HttpResponseMessage innerResult = new HttpResponseMessage(HttpStatusCode.OK);

        stream.Seek(0, SeekOrigin.Begin);
        innerResult.Content = new StreamContent(stream);
        innerResult.Content.Headers.ContentLength = stream.Length;
        innerResult.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");

        ContentDispositionHeaderValue contentDisposition = null;
        if (ContentDispositionHeaderValue.TryParse("inline; filename=" + filename + ".pdf", out contentDisposition))
        {
            innerResult.Content.Headers.ContentDisposition = contentDisposition;
        }
        return innerResult;
    }
}

我得到的错误是:

System.UnauthorizedAccessException: Access to the path 'C:\Sites\MySite\test.pdf' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode)
   at Workflow.Web.Controllers.WebApi.DocumentUIController.<DocumentPdfGet>d__11.MoveNext() in C:\agent\_work\10\s\....\Controllers\WebApi\MyControllerController.cs:line 220

但是当我将 FileStream 更改为 File.ReadAllBytes 时,我没有在服务器上收到拒绝访问,请参见下面的代码:

[HttpGet]
[Route("Document/Pdf/{id}")]
[ResponseType(typeof(HttpResponseMessage))]
public async Task<HttpResponseMessage> DocumentPdfGet(int id)
{
        string userName = User.Identity.Name;

        Byte[] pdfFile;
        string pdfPath = System.Web.HttpContext.Current.Server.MapPath("~/test.pdf");
        string filename = Path.GetFileName(pdfPath);
        HttpResponseMessage innerResult = new HttpResponseMessage(HttpStatusCode.OK);

        pdfFile = File.ReadAllBytes(pdfPath);
        ByteArrayContent byteArrayContent = new ByteArrayContent(pdfFile);

        innerResult.Content = byteArrayContent;
        innerResult.Content.Headers.ContentLength = pdfFile.Length;
        innerResult.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");

        ContentDispositionHeaderValue contentDisposition = null;
        if (ContentDispositionHeaderValue.TryParse("inline; filename=" + filename + ".pdf", out contentDisposition))
        {
            innerResult.Content.Headers.ContentDisposition = contentDisposition;
        }
        return innerResult;
}

当 System.IO.FileStream 导致访问冲突错误时,为什么 File.ReadAllBytes 在 IIS 服务器上工作?

【问题讨论】:

    标签: asp.net asp.net-web-api


    【解决方案1】:

    默认情况下,FileStream 使用FileAccess.ReadWrite,因此当您的应用程序没有写入权限时(可能就是这种情况),它会抛出错误。

    另一方面,File.ReadAllBytes 仅使用 FileAccess.Read,因此您的应用程序只需具有读取权限。

    那么如何修复您的代码?使用接受 FileAccess 参数的 FileStream 构造函数并将其设置为FileAccess.Read

    【讨论】:

    • 这完全有效 System.IO.FileStream stream = new FileStream(pdfPath, FileMode.Open, FileAccess.Read);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    • 2019-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多