1

하나의 Mvc4 응용 프로그램에서 다른 Mvc4 응용 프로그램으로 파일을 보내야합니다 (다른 하나는 Mvc4, WebApi 응용 프로그램입니다). 보내는 목적으로 HttpClient의 PostAsync 메서드를 사용하고 있습니다. 여기 전송을 수행하는 코드입니다 :PostAsync가 mscorlib에서 NullReferenceException을 throw합니다.

public class TestController : ApiController 
{ 
    // POST api/values 
    public Task<HttpResponseMessage> Post() 
    { 
     if (!Request.Content.IsMimeMultipartContent()) 
     { 
      throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); 
     } 

     string root = HttpContext.Current.Server.MapPath("~/App_Data"); 


     var provider = new MultipartFormDataStreamProvider(root); 


     // Read the form data and return an async task. 
     var task = Request.Content.ReadAsMultipartAsync(provider).ContinueWith(t => 
     { 
      if (t.IsFaulted || t.IsCanceled) 
      { 
       return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception); 
      } 

      // This illustrates how to get the file names. 
      foreach (MultipartFileData file in provider.FileData) 
      { 
       Trace.WriteLine(file.Headers.ContentDisposition.FileName); 
       Trace.WriteLine("Server file path: " + file.LocalFileName); 

      } 

      return new HttpResponseMessage 
      { 
       Content = new StringContent("File uploaded.") 
      }; 

      //var response = Request.CreateResponse(HttpStatusCode.OK); 

      //return response; 
     }); 

     return task; 
    } 
} 
:

public class HomeController : Controller 
{ 
    public async Task<ActionResult> Index() 
    { 
     var result = 
      await Upload("http://localhost/target/api/test/post", "Test", System.IO.File.Open(@"C:\SomeFile", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)); 

     return View(result); 
    } 

    public async Task<String> Upload(String url, string filename, Stream stream) 
    { 
     using (var client = new HttpClient()) 
     { 
      var formData = new MultipartFormDataContent(); 

      var fileContent = new StreamContent(stream); 

      var header = new ContentDispositionHeaderValue("attachment") { FileName = filename }; 

      fileContent.Headers.ContentDisposition = header; 

      formData.Add(fileContent); 

      var result = await client.PostAsync(url, formData); // Use your url here 

      return "123"; 
     } 
    } 
} 

를 수신의 목적을 위해, 내가 공식 웹 API를 튜토리얼에있는 예제 중 하나를 사용하고는, 여기를 수행하는 코드입니다

문제 :

수신기는 성공적으로 파일을 가져옵니다,하지만 때 다음과 같은 코드로 응답 :

return new HttpResponseMessage 
{ 
    Content = new StringContent("File uploaded.") 
}; 
,536,

.Net의 mscorlib 내부 깊숙한 곳에서 발신자 측이 깨집니다. try/catch를 사용하여 await 호출을 감싸더라도 예외는 처리되지 않습니다.

비동기 구현을 유지하고 동기화를 사용하고 싶지는 않습니까? 왜 문제가 발생합니까? 이견있는 사람?

+0

스택 추적을 포함하여 전체 예외를 게시 할 수 있습니까? – svick

답변

7

튜토리얼 코드를 다시 확인하십시오. this page에 대해 이야기하고 있다고 가정합니다.이 경우 이전 .NET 4.0 예제가 아닌 코드의 .NET 4.5 버전 (await)을 사용해야합니다.

ASP.NET intrinsic (HttpContext, 요청, 응답 등)은 요청 컨텍스트에서만 액세스 할 수 있습니다. 코드에서 을 지정하지 않고 ContinueWith을 사용하고 있습니다.이 경우 람다가 스레드 풀 외부에서 요청 컨텍스트 인에서 실행됩니다.

코드에서 은 전혀 사용하지 말아야합니다 (에 실제로이 필요하지 않는 한). 대신 await을 사용하십시오 :

// POST api/values 
public async Task<HttpResponseMessage> Post() 
{ 
    if (!Request.Content.IsMimeMultipartContent()) 
    { 
     throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); 
    } 

    string root = HttpContext.Current.Server.MapPath("~/App_Data"); 
    var provider = new MultipartFormDataStreamProvider(root); 

    try 
    { 
     // Read the form data. 
     await Request.Content.ReadAsMultipartAsync(provider); 

     // This illustrates how to get the file names. 
     foreach (MultipartFileData file in provider.FileData) 
     { 
      Trace.WriteLine(file.Headers.ContentDisposition.FileName); 
      Trace.WriteLine("Server file path: " + file.LocalFileName); 
     } 

     return new HttpResponseMessage 
     { 
      Content = new StringContent("File uploaded.") 
     }; 
    } 
    catch (Exception ex) 
    { 
     return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex); 
    } 
} 
+0

고마워,이 문제는 언젠가 해결해야만했다. – Lu4

관련 문제