visual tag studio sharp propiedad fuente documentar documentacion crear como codigo clases c# asp.net-mvc-4

c# - tag - summary c sharp



Cómo aceptar un archivo POST (12)

Estoy usando asp.net mvc 4 webapi beta para construir un servicio de descanso. Necesito poder aceptar imágenes / archivos de POST de aplicaciones cliente. ¿Es esto posible usando el webapi? A continuación se muestra cómo acción estoy usando actualmente. ¿Alguien sabe de un ejemplo de cómo debería funcionar esto?

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


Aquí hay dos formas de aceptar un archivo. Uno que utiliza el proveedor de memoria MultipartMemoryStreamProvider y otro que usa MultipartFormDataStreamProvider que se guarda en un disco. Tenga en cuenta que esto es solo para un archivo subido a la vez. Usted puede ampliar esto con certeza para guardar varios archivos. El segundo enfoque puede soportar archivos grandes. He probado archivos de más de 200MB y funciona bien. El uso del enfoque de memoria no requiere que guarde en el disco, pero se eliminará de la excepción de memoria si supera un cierto límite.

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


Aquí hay una solución rápida y sucia que toma el contenido del archivo cargado desde el cuerpo HTTP y lo escribe en un archivo. Incluí un fragmento HTML / JS "básico" para la carga del archivo.

Método de API web:

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

Carga de archivos 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>


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


En esta misma dirección, estoy publicando un recorte de clientes y servidores que envían archivos de Excel usando WebApi, c # 4:

public static void SetFile(String serviceUrl, byte[] fileArray, String fileName) { try { using (var client = new HttpClient()) { client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); using (var content = new MultipartFormDataContent()) { var fileContent = new ByteArrayContent(fileArray);//(System.IO.File.ReadAllBytes(fileName)); fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = fileName }; content.Add(fileContent); var result = client.PostAsync(serviceUrl, content).Result; } } } catch (Exception e) { //Log the exception } }

Y el controlador webapi del servidor:

public Task<IEnumerable<string>> Post() { if (Request.Content.IsMimeMultipartContent()) { string fullPath = HttpContext.Current.Server.MapPath("~/uploads"); MyMultipartFormDataStreamProvider streamProvider = new MyMultipartFormDataStreamProvider(fullPath); var task = Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(t => { if (t.IsFaulted || t.IsCanceled) throw new HttpResponseException(HttpStatusCode.InternalServerError); var fileInfo = streamProvider.FileData.Select(i => { var info = new FileInfo(i.LocalFileName); return "File uploaded as " + info.FullName + " (" + info.Length + ")"; }); return fileInfo; }); return task; } else { throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "Invalid Request!")); } }

Y el MyMultipartFormDataStreamProvider personalizado, necesario para personalizar el nombre de archivo:

PD: tomé este código de otra publicación http://www.codeguru.com/csharp/.net/uploading-files-asynchronously-using-asp.net-web-api.htm

public class MyMultipartFormDataStreamProvider : MultipartFormDataStreamProvider { public MyMultipartFormDataStreamProvider(string path) : base(path) { } public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers) { string fileName; if (!string.IsNullOrWhiteSpace(headers.ContentDisposition.FileName)) { fileName = headers.ContentDisposition.FileName; } else { fileName = Guid.NewGuid().ToString() + ".data"; } return fileName.Replace("/"", string.Empty); } }


Esta pregunta tiene muchas respuestas buenas incluso para .Net Core. Estaba usando ambos Frameworks, los ejemplos de código provistos funcionan bien. Así que no lo repetiré. En mi caso, lo importante era cómo usar las acciones de carga de archivos con Swagger esta manera:

Aquí está mi resumen:

ASP .Net WebAPI 2

  • Para cargar el uso del archivo: MultipartFormDataStreamProvider vea las respuestas aquí
  • Cómo usarlo con Swagger

.NET Core


La forma principal de ASP.NET ahora está here :

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


Me sorprende que muchos de ustedes parecen querer guardar archivos en el servidor. La solución para mantener todo en la memoria es la siguiente:

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


Tuve un problema similar para la API web de vista previa. Todavía no se ha transferido esa parte a la nueva API web de MVC 4, pero quizás esto ayude:

Carga de archivos REST con HttpRequestMessage o Stream?

Por favor, hágamelo saber, puede sentarse mañana e intentar implementarlo de nuevo.


Utilicé la respuesta de Mike Wasson antes de actualizar todos los NuGets en mi proyecto webapi mvc4. Una vez que lo hice, tuve que volver a escribir la acción de subir el archivo:

public Task<HttpResponseMessage> Upload(int id) { HttpRequestMessage request = this.Request; if (!request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(new HttpResponseMessage(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 => { FileInfo finfo = new FileInfo(provider.FileData.First().LocalFileName); string guid = Guid.NewGuid().ToString(); File.Move(finfo.FullName, Path.Combine(root, guid + "_" + provider.FileData.First().Headers.ContentDisposition.FileName.Replace("/"", ""))); return new HttpResponseMessage() { Content = new StringContent("File uploaded.") }; } ); return task; }

Al parecer, BodyPartFileNames ya no está disponible dentro del MultipartFormDataStreamProvider.


Vea el código a continuación, adaptado de este artículo , que muestra el código de ejemplo más simple que pude encontrar. Incluye las cargas de archivos y de memoria (más rápidas).

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


vea http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-2 , aunque creo que el artículo lo hace un poco más complicado de lo que parece realmente es.

Básicamente,

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


[HttpPost] public JsonResult PostImage(HttpPostedFileBase file) { try { if (file != null && file.ContentLength > 0 && file.ContentLength<=10485760) { var fileName = Path.GetFileName(file.FileName); var path = Path.Combine(Server.MapPath("~/") + "HisloImages" + "//", fileName); file.SaveAs(path); #region MyRegion ////save imag in Db //using (MemoryStream ms = new MemoryStream()) //{ // file.InputStream.CopyTo(ms); // byte[] array = ms.GetBuffer(); //} #endregion return Json(JsonResponseFactory.SuccessResponse("Status:0 ,Message: OK"), JsonRequestBehavior.AllowGet); } else { return Json(JsonResponseFactory.ErrorResponse("Status:1 , Message: Upload Again and File Size Should be Less Than 10MB"), JsonRequestBehavior.AllowGet); } } catch (Exception ex) { return Json(JsonResponseFactory.ErrorResponse(ex.Message), JsonRequestBehavior.AllowGet); } }