Lu4*_*Lu4 1 .net async-await asp.net-mvc-4 asp.net-web-api dotnet-httpclient
我需要从一个Mvc4应用程序发送文件到另一个(另一个是Mvc4,WebApi应用程序).为了发送我使用HttpClient的PostAsync方法.以下是执行发送的代码:
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";
}
}
}
Run Code Online (Sandbox Code Playgroud)
为了接收,我使用官方web 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;
}
}
Run Code Online (Sandbox Code Playgroud)
接收方成功获取文件,但是当它使用以下代码进行响应时:
return new HttpResponseMessage
{
Content = new StringContent("File uploaded.")
};
Run Code Online (Sandbox Code Playgroud)
发送方是在.Net的mscorlib内部深处的某个地方打破.即使我await用try/catch 包装调用,也不会处理异常.
我想保留异步实现,不想使用同步,这可能吗?为什么会出现问题?有什么想法吗?
仔细检查您的教程代码.我假设你在谈论这个页面,在这种情况下你应该使用.NET 4.5版本的代码(with await),而不是旧的.NET 4.0示例.
ASP.NET内在函数(HttpContext,请求,响应等)只能从请求上下文中访问.您的代码正在使用ContinueWith而未指定a 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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2244 次 |
| 最近记录: |