2017-02-14 4 views
6

Ich bin nicht in der Lage, herauszufinden, wie Sie eine .NET Core Web API schreiben, um den Datei-Upload zu unterstützen. Bitte beachten Sie, dass ich das ASP.NET Core MVC-Formular nicht zum Hochladen von Dateien, sondern über einen Servlet/JSP-Container verwende. Hier ist, wie mein project.json definiert ist,.NET Core - Web API - Wie wird der Datei-Upload durchgeführt?

{ 
    "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%" ] 
    } 
} 

Hier ist, wie mein Startup definiert ist,

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

Schließlich ist hier, wie mein -Controller definiert ist,

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

Ich habe diese Li durchlaufen nk, https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads aber kann einfach nicht funktionieren! Jede Hilfe wird geschätzt !!!

ich die Google Advanced REST-Client verwende die Daten zu schreiben, wie folgt This is how I am sending the POST request

ich Antwort bekommen immer mit folgenden Meldung ist fehlgeschlagen ... Status: 500: Interner Serverfehler Ladezeit: 62 ms Response-Header Anfrage Header Redirects Timings Content-Type: multipart/form-data; boundary = ---- WebKitFormBoundary0RKUhduCjSNZOEMN Content-Length: 9106 Quelle Nachricht

POST/api/Attachments HTTP/1.1 HOST: localhost: 52770 content-type: multipart/form-data; boundary = ---- WebKitFormBoundary0RKUhduCjSNZOEMN Content-Length: 9106

------ WebKitFormBoundary0RKUhduCjSNZOEMN Content-Disposition: Form-Daten; name = "fileUpload1"; filename = "1i4ymeoyov_In_the_Wild_Testing.png" Content-Type: image/png

PNG

IHDR, I3 (tEXtSoftwareAdobe ImageReadyqe < 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--

+0

Beachten Sie, dass in ASP.NET-Core gibt es keine Unterscheidung zwischen MVC und Web API (nur FYI) .. – ssmith

Antwort

0

im request, Ihre URL ist nicht korrekt. Überprüfen sie die Route auf dem Controller, es ist [Route ("api/[controller]")] und der Name der Aktionsmethode lautet PostFiles. So wird die korrekte URL http://localhost:52770/api/Attachments/PostFiles

entweder die URL korrigieren oder die Aktionsmethode als Index umbenennen

+0

Pradeep danke für die Antwort. – Rohit

+0

Ich versuchte beide Wege, aber kein Glück. Wenn ich die URL als 'http: // localhost: 52770/api/Anhänge/PostFiles' verwende, bekomme ich HTTP 404 als Antwort. Wenn ich die Aktionsmethode als Index neu definiere, bekomme ich '500: Interner Serverfehler' als Antwort. Bitte beachten Sie, dass ich den Namen des Parameters in Dateien geändert habe, als ich Dateien in "Google's ARC" ausgewählt habe, die zum Hochladen der Anfrage an die .NET Core Web API verwendet wurden. – Rohit

+0

Wenn Sie den Namen der Aktionsmethode als Index verwenden, können Sie die Aktionsmethode zum Debuggen verwenden? Eine weitere Sache, Path.GetTempFileName() erstellt eine temporäre Datei im temporären Ordner des Benutzers. Die App hat möglicherweise keine Berechtigung dazu. Versuchen Sie einen anderen Pfad var uploads = Path.Combine (_environment.WebRootPath, "uploads"); foreach (var Datei in Dateien) {if (file.length> 0) {using (var filestream = new Filestream (Path.Combine (Uploads, file.FileName), FileMode.Create)) { erwarten file.CopyToAsync (fileStream);} } } –

0

Ich denke, das Problem auf einen Fehler in Chrom 56 zurückzuführen ist.

ARC can't send files on new Chrome version: 56.0.2924.76

Dieses Problem betrifft sowohl Postbote und ChromeRestClient

Die einfache Abhilfe Use XHR Option aktivieren und den Header Content-Type entfernen: multipart/form-data.

Dies funktioniert sowohl für Postbote und Chrom

4

Dies ist die Ursache: Form-Daten; name = „fileUpload1“

Ihr Name „fileUpload1“ hat „Dateien“ sein, die die Deklaration der Aktion Postfiles entspricht (ICollection < IFormFile> Dateien)

Verwandte Themen