1

我需要从一个Mvc4应用程序发送文件到另一个(另一个是Mvc4,WebApi应用程序)。为了发送的目的,我使用HttpClient的PostAsync方法。以下是处理发送代码:等待PostAsync在mscorlib中抛出NullReferenceException

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教程中的一个例子,在这里是做它的代码:

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; 
    } 
} 

问题:

接收机获得文件成功,但是当它用下面的代码响应:

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

发件人端在.Net的mscorlib内部内部深处发生了断裂。即使我用try/catch包装await调用,也不处理异常。

我想保持异步实现,不想使用同步一个,这是可能的吗?为什么会出现这个问题?有什么想法吗?

+0

您可以发布完整例外,包括堆栈跟踪吗? – svick

回答

7

仔细检查您的教程代码。我假设你在讨论this page,在这种情况下,你应该使用.NET 4.5版本的代码(使用await),而不是旧的.NET 4.0例子。

只能从请求上下文访问ASP.NET内部函数(HttpContext,请求,响应等)。您的代码使用ContinueWith,但未指定TaskScheduler,在这种情况下,这将导致该lambda在线程池之外的之外的请求上下文中运行。

async代码,你不应该使用在所有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

相关问题