문제

이 페이지의 의견에서 :

http://msdn.microsoft.com/en-us/library/12s31dhy%28v=vs.90%29.aspx

.. 송전 파일 ()은 UNC 공유와 함께 사용할 수 없다고 말합니다. 내가 알 수있는 한, 이것이 사실입니다. 시도 할 때 이벤트 로그 에서이 오류가 발생합니다.

TransmitFile failed. File Name: \\myshare1\e$\file.zip, Impersonation Enabled: 0, Token Valid: 1, HRESULT: 0x8007052e

제안 된 대안은 writefile ()을 사용하는 것이지만 파일을 메모리에로드하기 때문에 문제가됩니다. 내 응용 프로그램에서 파일은> 200MB이므로 확장되지 않습니다.

ASP.NET에는 사용자에게 파일을 스트리밍하는 방법이 있습니까?

  • 확장 가능 (전체 파일을 RAM으로 읽거나 ASP.NET 스레드를 점유하지 않음)
  • UNC 공유와 함께 작동합니다

가상 디렉토리로 네트워크 드라이브를 매핑하는 것은 우리에게 옵션이 아닙니다. 파일을 로컬 웹 서버에 복사하지 않으려 고합니다.

감사

도움이 되었습니까?

해결책

원격 UNC 경로를 홈 디렉토리로 사용하여 IIS vRoot를 설정해 보셨습니까? 작동하면 가장 쉬운 솔루션 일 수 있습니다. 파일의 인증 장벽 (예 : httpmodule을 통해 또는 아마도 박스 외 양식 인증 모듈을 통해조차도)의 인증 장벽을 시행 할 수 있지만, 인증 필터가 이동 한 후에는 IIS에 의존하여 컨텐츠를 효율적으로 스트리밍 할 수 있습니다.

경고 : UNC 시나리오에서 IIS를 마지막으로 구성한 것은 오래 전 (1998 !!!)였으며 원격 시스템에 파일이 잠겨있는 경우 간헐적 인 문제를 해결하여 파일을 업데이트하는 데 문제가 발생했습니다. UNC 서버 재부팅 후 복구를 다루는 것도 흥미로 웠습니다. 나는 11 년 동안 그 이후로 그 문제가 해결되었다고 생각하지만, 당신은 결코 확신 할 수 없습니다!

또 다른 방법은 UNC 시스템에 웹 서버를 설치 한 다음 새 새와 같이 웹 서버에 리버스 프록시 서버를 설치하는 것입니다. IIS7 응용 프로그램 요청 라우팅 기준 치수.

서버 스레드를 기꺼이 묶으려면 권장되는 접근 방식을 사용할 수 있습니다. KB812406 RAM 소비, 시간 초과, 클라이언트 단절 등과 관련된 문제를 다루는 등 반응 버퍼링을 끄십시오!

이상적인 최대 제어 솔루션은 "스트리밍 httphandler"이며, 출력을 한 번에 보내는 대신 스트림을 ASP.NET으로 반환하고 ASP.NET가 고객에게 청크 결과에 대한 세부 사항을 처리하게 할 수 있습니다. , 연결 끊김 등을 다루는 등은이 작업을 수행하는 좋은 방법을 찾을 수 없었습니다. :-(

다른 팁

당신이 시도 할 수있는 것은 FileStream, 파일 청크를 읽기 위해 루프를 사용하여 청크를 전송합니다 (사용 Response.Write(Char[], Int32, Int32)), 청크를 폐기하고 파일을 완전히 읽을 때까지 반복하십시오.

파일을 로컬 디렉토리에 작성하고 로보 코피 작업이 디렉토리를 모니터링하여 사본을 수행 할 수 있습니다.

그러나 로컬 서버에 쓰기를 피하려고하므로 대상 서버에 서버 (http 또는 ftp, 예를 들어)를 투입하고 해당 서비스에 파일을 작성하는 것을 조사 할 수 있습니다.

UNC를 가리키는 다른 IIS 웹 사이트를 설정 한 다음 해당 웹 사이트의 파일로 리디렉션 할 수 있습니까?

Response.redirect ( "http://files.somewhere.com/some/file.blah");

이렇게하면 별도의 작업자 프로세스에서 실행되며 현재 사이트에 영향을 미치지 않으며 파일은 IIS에 의해 직접 제공됩니다.

다시 돌아온 실제 오류는 파일 공유에 대한 로그온 실패였습니다 (사용자 IIS가 실행 중일 가능성이 높고 관리 공유에 액세스하려고 할 가능성이 크지 않습니다). 전송 파일의 특정 한도가 아닌 문제인지 확인하기 위해 액세스 제한이없는 주식을 설정하려고 했습니까?

그것이 수정되면 해당 공유에 해당 공유에 로그인하거나 현재 사용자로서의 공유에 로그인하거나 권한이있는 사용자를 가장합니다.

반사기 Transmitfile을 둘러 보는 Abit 후에는 파일을 어쨌든 메모리로 읽을 수 있으며 WriteFile은 파일을 메모리에 읽을 것인지 아닌지 ( 사실 기본 writefile 은이 매개 변수에 대해 False를 전달합니다). 코드에서 찌르는 가치가있을 수 있습니다.

두 번째 사이트 접근법을 추천하고 토큰 기반 인증 메커니즘을 구현합니다. 리디렉션을 통해 클라이언트에게 전달 된 URL에서 인증 쿠키를 인코딩합니다. 이것은 비하인드 스토리를 공유하는 불투명 값 일 수 있거나 비밀 암호와 현재 날짜의 해시만큼 간단 할 수 있습니다.

내가 해싱을 사용한 하나의 프로젝트. 하나의 서버는 공유 비밀 암호와 연장 번호의 해시를 생성했습니다. 두 번째 서버 (다른 네트워크에 있던)는 동일한 비밀번호와 확장자를 가져 와서 해시를 해당 연장에서 원하는 전화 번호로 통화 할 수 있음을 확인했습니다.

TransmitFile의 코드는 매우 간단합니다. 필요한 작업을 수행하도록 수정하지 않겠습니까?

public void TransmitFile(string filename, long offset, long length)
{
    if (filename == null)
    {
        throw new ArgumentNullException("filename");
    }
    if (offset < 0L)
    {
        throw new ArgumentException(SR.GetString("Invalid_range"), "offset");
    }
    if (length < -1L)
    {
        throw new ArgumentException(SR.GetString("Invalid_range"), "length");
    }
    filename = this.GetNormalizedFilename(filename);
    using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        long num = stream.Length;
        if (length == -1L)
        {
            length = num - offset;
        }
        if (num < offset)
        {
            throw new ArgumentException(SR.GetString("Invalid_range"), "offset");
        }
        if ((num - offset) < length)
        {
            throw new ArgumentException(SR.GetString("Invalid_range"), "length");
        }
        if (!this.UsingHttpWriter)
        {
            this.WriteStreamAsText(stream, offset, length);
            return;
        }
    }
    if (length > 0L)
    {
        bool supportsLongTransmitFile = (this._wr != null) && this._wr.SupportsLongTransmitFile;
        this._httpWriter.TransmitFile(filename, offset, length, this._context.IsClientImpersonationConfigured || HttpRuntime.IsOnUNCShareInternal, supportsLongTransmitFile);
    }
}



private void WriteStreamAsText(Stream f, long offset, long size)
{
    if (size < 0L)
    {
        size = f.Length - offset;
    }
    if (size > 0L)
    {
        if (offset > 0L)
        {
            f.Seek(offset, SeekOrigin.Begin);
        }
        byte[] buffer = new byte[(int) size];
        int count = f.Read(buffer, 0, (int) size);
        this._writer.Write(Encoding.Default.GetChars(buffer, 0, count));
    }
}


internal void TransmitFile(string filename, long offset, long size, bool isImpersonating, bool supportsLongTransmitFile)
{
    if (this._charBufferLength != this._charBufferFree)
    {
        this.FlushCharBuffer(true);
    }
    this._lastBuffer = null;
    this._buffers.Add(new HttpFileResponseElement(filename, offset, size, isImpersonating, supportsLongTransmitFile));
    if (!this._responseBufferingOn)
    {
        this._response.Flush();
    }
}

감사,

필.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top