我正在使用asp.net mvc 4 webapi beta来构建一个休息服务。我需要能够接受张贴的图像/文件从客户端应用程序。这可能使用webapi吗?下面是如何行动,我目前正在使用。有人知道一个例子吗?

[HttpPost]
public string ProfileImagePost(HttpPostedFile profileImage)
{
    string[] extensions = { ".jpg", ".jpeg", ".gif", ".bmp", ".png" };
    if (!extensions.Any(x => x.Equals(Path.GetExtension(profileImage.FileName.ToLower()), StringComparison.OrdinalIgnoreCase)))
    {
        throw new HttpResponseException("Invalid file type.", HttpStatusCode.BadRequest);
    }

    // Other code goes here

    return "/path/to/image.png";
}

当前回答

这个问题甚至对于。net Core也有很多好的答案。我使用这两个框架提供的代码示例工作良好。我就不重复了。在我的例子中,重要的事情是如何使用Swagger的文件上传动作,就像这样:

以下是我的概述:

2 . asp.net WebAPI

上传文件使用:MultipartFormDataStreamProvider见答案在这里 如何使用它与Swagger

net核心

上传文件使用:IFormFile见答案在这里或MS文档 如何使用它与Swagger

其他回答

这里有两种接受文件的方法。一个使用内存提供程序MultipartMemoryStreamProvider,另一个使用保存到磁盘的MultipartFormDataStreamProvider。注意,这一次只针对一个文件上传。您可以扩展它来保存多个文件。第二种方法可以支持大文件。我测试过超过200MB的文件,它工作得很好。使用内存方法不需要保存到磁盘,但如果超过一定的限制,将抛出内存外异常。

private async Task<Stream> ReadStream()
{
    Stream stream = null;
    var provider = new MultipartMemoryStreamProvider();
    await Request.Content.ReadAsMultipartAsync(provider);
    foreach (var file in provider.Contents)
    {
        var buffer = await file.ReadAsByteArrayAsync();
        stream = new MemoryStream(buffer);
    }

    return stream;
}

private async Task<Stream> ReadLargeStream()
{
    Stream stream = null;
    string root = Path.GetTempPath();
    var provider = new MultipartFormDataStreamProvider(root);
    await Request.Content.ReadAsMultipartAsync(provider);
    foreach (var file in provider.FileData)
    {
        var path = file.LocalFileName;
        byte[] content = File.ReadAllBytes(path);
        File.Delete(path);
        stream = new MemoryStream(content);
    }

    return stream;
}

我在预览Web API时遇到了类似的问题。还没有将这部分移植到新的MVC 4 Web API,但这可能会有所帮助:

使用HttpRequestMessage或Stream上传REST文件?

请让我知道,可以坐下来,明天再试着实施它。

下面的代码改编自本文,它演示了我能找到的最简单的示例代码。它包括文件和内存(更快)上传。

public HttpResponseMessage Post()
{
    var httpRequest = HttpContext.Current.Request;
    if (httpRequest.Files.Count < 1)
    {
        return Request.CreateResponse(HttpStatusCode.BadRequest);
    }

    foreach(string file in httpRequest.Files)
    {
        var postedFile = httpRequest.Files[file];
        var filePath = HttpContext.Current.Server.MapPath("~/" + postedFile.FileName);
        postedFile.SaveAs(filePath);
        // NOTE: To store in memory use postedFile.InputStream
    }

    return Request.CreateResponse(HttpStatusCode.Created);
}

下面是一个快速而简单的解决方案,它从HTTP正文中获取上传的文件内容并将其写入文件。我为文件上传包含了一个“骨架”HTML/JS片段。

Web API方法:

[Route("api/myfileupload")]        
[HttpPost]
public string MyFileUpload()
{
    var request = HttpContext.Current.Request;
    var filePath = "C:\\temp\\" + request.Headers["filename"];
    using (var fs = new System.IO.FileStream(filePath, System.IO.FileMode.Create))
    {
        request.InputStream.CopyTo(fs);
    }
    return "uploaded";
}

HTML文件上传:

<form>
    <input type="file" id="myfile"/>  
    <input type="button" onclick="uploadFile();" value="Upload" />
</form>
<script type="text/javascript">
    function uploadFile() {        
        var xhr = new XMLHttpRequest();                 
        var file = document.getElementById('myfile').files[0];
        xhr.open("POST", "api/myfileupload");
        xhr.setRequestHeader("filename", file.name);
        xhr.send(file);
    }
</script>

ASP。NET Core的方式现在在这里:

[HttpPost("UploadFiles")]
public async Task<IActionResult> Post(List<IFormFile> files)
{
    long size = files.Sum(f => f.Length);

    // full path to file in temp location
    var filePath = Path.GetTempFileName();

    foreach (var formFile in files)
    {
        if (formFile.Length > 0)
        {
            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await formFile.CopyToAsync(stream);
            }
        }
    }

    // process uploaded files
    // Don't rely on or trust the FileName property without validation.

    return Ok(new { count = files.Count, size, filePath});
}