начинающих - mvc c#




Как принять файл POST (8)

Вот быстрое и грязное решение, которое берет загруженное содержимое файла из тела 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 mvc 4 webapi beta для создания службы отдыха. Мне нужно принять POSTed изображения / файлы из клиентских приложений. Возможно ли это с помощью 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";
}

Вот два способа принять файл. Один использует в памяти поставщика MultipartMemoryStreamProvider и один использует MultipartFormDataStreamProvider, который сохраняет на диск. Обратите внимание: это только для загрузки одного файла за раз. Вы можете определенно расширить это, чтобы сохранить несколько файлов. Второй подход может поддерживать большие файлы. Я тестировал файлы более 200 МБ, и он отлично работает. Использование в подходе к памяти не требует сохранения на диск, но исключает исключение из памяти, если вы превысите определенный предел.

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

Контроллер API:

[HttpPost]
public HttpResponseMessage Post()
{

        HttpRequestMessage request = this.Request;

            if (!request.Content.IsMimeMultipartContent() || System.Web.HttpContext.Current.Request.Files.Count < 1)
            {
               //TODO
            }
            else
            {
                string root = System.Web.HttpContext.Current.Server.MapPath("~/App_Data");
                var provider = new MultipartFormDataStreamProvider(root);

                try
                {
                    Request.Content.ReadAsMultipartAsync(provider);
                    List<String> payload = new List<string>();

                    foreach (var file in provider.FileData)
                    {                       
                        var path = file.LocalFileName;
                        byte[] byteArray = File.ReadAllBytes(path);

                    }

                }
                catch (System.Exception e)
                {
                    //TODO
                }
            }


    return Request.CreateResponse(HttpStatusCode.Created);
}

См. Приведенный ниже код, адаптированный из этой статьи , который демонстрирует простейший примерный код, который я мог найти. Он включает в себя как файлы, так и память (быстрее).

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

У меня была аналогичная проблема для веб-API предварительного просмотра. Не переносил эту часть в новый MVC 4 Web API, но, возможно, это помогает:

Загрузка файла REST с помощью HttpRequestMessage или Stream?

Пожалуйста, дайте мне знать, завтра можете сесть и попытаться реализовать его снова.


У этого вопроса есть много хороших ответов даже для .Net Core. Я использовал оба Frameworks, чтобы предоставленные образцы кода работали нормально. Поэтому я не буду повторять это. В моем случае важно было, как использовать действия по загрузке файлов с помощью Swagger следующим образом:

Вот мое резюме:

ASP. Net WebAPI 2

.NET Core


Я удивлен, что многие из вас, похоже, хотят сохранить файлы на сервере. Решение сохранить все в памяти выглядит следующим образом:

[HttpPost, Route("api/upload")]
public async Task<IHttpActionResult> Upload()
{
    if (!Request.Content.IsMimeMultipartContent())
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); 

    var provider = new MultipartMemoryStreamProvider();
    await Request.Content.ReadAsMultipartAsync(provider);
    foreach (var file in provider.Contents)
    {
        var filename = file.Headers.ContentDisposition.FileName.Trim('\"');
        var buffer = await file.ReadAsByteArrayAsync();
        //Do whatever you want with filename and its binary data.
    }

    return Ok();
}

см. http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-2 , хотя я думаю, что эта статья кажется немного более сложной, чем она на самом деле.

В принципе,

public Task<HttpResponseMessage> PostFile() 
{ 
    HttpRequestMessage request = this.Request; 
    if (!request.Content.IsMimeMultipartContent()) 
    { 
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); 
    } 

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

    var task = request.Content.ReadAsMultipartAsync(provider). 
        ContinueWith<HttpResponseMessage>(o => 
    { 

        string file1 = provider.BodyPartFileNames.First().Value;
        // this is the file name on the server where the file was saved 

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




asp.net-mvc-4