I am not able to figure out, how to write a .NET Core Web API to support File Upload. Please note I am not using ASP.NET Core MVC form for file upload but via a Servlet/JSP container. Here is how my project.json is defined,
{ "dependencies": { "Microsoft.NETCore.App": { "version": "1.0.1", "type": "platform" }, "Microsoft.AspNetCore.Mvc": "1.0.1", "Microsoft.AspNetCore.Routing": "1.0.1", "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", "Microsoft.AspNetCore.Server.Kestrel": "1.0.1", "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0", "Microsoft.Extensions.Configuration.Json": "1.0.0", "Microsoft.Extensions.Logging": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0", "Microsoft.Extensions.Logging.Debug": "1.0.0", "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", "Npgsql": "3.1.9", "CoreCompat.Newtonsoft.Json": "9.0.2-beta001", "Newtonsoft.Json": "9.0.1" }, "tools": { "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final" }, "frameworks": { "netcoreapp1.0": { "imports": [ "dotnet5.6", "portable-net45+win8" ] } }, "buildOptions": { "emitEntryPoint": true, "preserveCompilationContext": true }, "runtimeOptions": { "configProperties": { "System.GC.Server": true } }, "publishOptions": { "include": [ "wwwroot", "**/*.cshtml", "appsettings.json", "web.config" ] }, "scripts": { "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] } } Here is how my Startup is defined,
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using QCService.Models; namespace QCService { public class Startup { public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddEnvironmentVariables(); Configuration = builder.Build(); } public IConfigurationRoot Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); //Add SurveysRepository for Dependency Injection services.AddSingleton<ISurveysRepository, SurveysRepository>(); //Add FeedbacksRepository for Dependency Injection services.AddSingleton<IFeedbacksRepository, FeedbacksRepository>(); //Add AttachmentsRepository for Dependency Injection services.AddSingleton<IAttachmentsRepository, AttachmentsRepository>(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); app.UseMvc(); } } } Finally here is how my Controller is defined,
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; //Including model classes for Attachments using QCService.Models; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Hosting; using System.IO; using Microsoft.Net.Http.Headers; // For more information on enabling Web API for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860 namespace QCService.Controllers { [Route("api/[controller]")] public class AttachmentsController : Controller { public IAttachmentsRepository AttachmentItems { get; set; } public AttachmentsController(IAttachmentsRepository attachmentItems) { AttachmentItems = attachmentItems; } // GET: api/Attachments [HttpGet] /*http://localhost:52770/api/Attachments*/ public IEnumerable<Attachments> Get() { return AttachmentItems.GetAllAttachments(); } // GET api/Attachments/5 [HttpGet("{id}")] /*http://localhost:52770/api/Attachments/{AttachmentID}*/ public Attachments Get(int id) { return AttachmentItems.GetAttachment(id); } // GET api/Attachments/5 [HttpGet("Feedback/{id}")] /*http://localhost:52770/api/Attachments/Feedback/{FeedbackID}*/ public IEnumerable<Attachments> GetFeedbackAttachments(int id) { return AttachmentItems.GetFeedbackAttachments(id); } // POST api/Attachments [HttpPost]/*http://localhost:52770/api/Attachments/*/ public async Task<IActionResult> PostFiles(ICollection<IFormFile> files) { try { System.Console.WriteLine("You received the call!"); WriteLog("PostFiles call received!", true); //We would always copy the attachments to the folder specified above but for now dump it wherver.... long size = files.Sum(f => f.Length); // full path to file in temp location var filePath = Path.GetTempFileName(); var fileName = Path.GetTempFileName(); foreach (var formFile in files) { if (formFile.Length > 0) { using (var stream = new FileStream(filePath, FileMode.Create)) { await formFile.CopyToAsync(stream); //formFile.CopyToAsync(stream); } } } // process uploaded files // Don't rely on or trust the FileName property without validation. //Displaying File Name for verification purposes for now -Rohit return Ok(new { count = files.Count, fileName, size, filePath }); } catch (Exception exp) { System.Console.WriteLine("Exception generated when uploading file - " + exp.Message); WriteLog("Exception generated when uploading file - " + exp.Message, true); string message = $"file / upload failed!"; return Json(message); } } /// <summary> /// Writes a log entry to the local file system /// </summary> /// <param name="Message">Message to be written to the log file</param> /// <param name="InsertNewLine">Inserts a new line</param> public void WriteLog(string Message, bool InsertNewLine) { LogActivity ologObject = null; try { string MessageString = (InsertNewLine == true ? Environment.NewLine : "") + Message; if (ologObject == null) ologObject = LogActivity.GetLogObject(); ologObject.WriteLog(Message, InsertNewLine); } catch (Exception ex) { Console.WriteLine("Unable to write to the log file : " + ex.Message); Console.WriteLine("Stack Trace : " + ex.StackTrace); } } } } I have gone through this link, https://learn.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads but just can't make it work! Any help is appreciated!!!
I am using the Google's Advanced Rest Client to post the data as follows, This is how I am sending the POST request
I keep getting response failed with following message... Status: 500: Internal Server Error Loading time: 62 ms Response headers 5 Request headers 2 Redirects 0 Timings Content-Type: multipart/form-data; boundary=----WebKitFormBoundary0RKUhduCjSNZOEMN Content-Length: 9106 Source message
POST /api/Attachments HTTP/1.1 HOST: localhost:52770 content-type: multipart/form-data; boundary=----WebKitFormBoundary0RKUhduCjSNZOEMN content-length: 9106
------WebKitFormBoundary0RKUhduCjSNZOEMN Content-Disposition: form-data; name="fileUpload1"; filename="1i4ymeoyov_In_the_Wild_Testing.png" Content-Type: image/png
�PNG
IHDR,I�3(tEXtSoftwareAdobe ImageReadyq�e< iTXtXML:com.adobe.xmp �8 ^2IDATx��] pU����@ a�H� Pe�P8 ��Ȉ��b�̌3�p�q�*�7"�h�+Yf��O�atD��(<�h¦DLXdOH ������=}���}ov8_U�..... ------WebKitFormBoundary0RKUhduCjSNZOEMN--