简体   繁体   中英

Ng-File-Upload with MVC & Web API - keep getting “404 Not Found”

I need to allow image upload in my AngularJS + WebAPI project. to achieve this I am using ng-file-upload according to this sample code: http://monox.mono-software.com/blog/post/Mono/233/Async-upload-using-angular-file-upload-directive-and-net-WebAPI-service/

with a few adjustments to the post code to look like this:

$scope.onFileSelect = function ($files) {
    console.log("on file select is running!");
    //$files: an array of files selected, each file has name, size, and type.
    for (var i = 0; i < $files.length; i++) {
        var $file = $files[i];
        (function (index) {
            Upload.upload({
                url: "/api/Uploads/Upload", // webapi url
                method: "POST",                   
                file: $file
            }).progress(function (evt) {
                // get upload percentage
                console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
            }).success(function (data, status, headers, config) {
                // file is uploaded successfully
                console.log(data);
            }).error(function (data, status, headers, config) {
                // file failed to upload
                console.log(data);
            });
        })(i);
    }
}

I have quite a few web API controllers already and I added a new one according to the code sample in the link above (that inherits from System.web.http.ApiController instead of the "regular" Microsoft.AspNet.Mvc.Controller class):

 [Route("api/[controller]")]
public class UploadsController : ApiController
{
    [HttpPost] // This is from System.Web.Http, and not from System.Web.Mvc        
    public async Task<HttpResponseMessage> Upload()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            this.Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
        }

        var provider = GetMultipartProvider();
        var result = await Request.Content.ReadAsMultipartAsync(provider);

        // On upload, files are given a generic name like "BodyPart_26d6abe1-3ae1-416a-9429-b35f15e6e5d5"
        // so this is how you can get the original file name
        var originalFileName = GetDeserializedFileName(result.FileData.First());

        // uploadedFileInfo object will give you some additional stuff like file length,
        // creation time, directory name, a few filesystem methods etc..
        var uploadedFileInfo = new FileInfo(result.FileData.First().LocalFileName);



        // Through the request response you can return an object to the Angular controller
        // You will be able to access this in the .success callback through its data attribute
        // If you want to send something to the .error callback, use the HttpStatusCode.BadRequest instead
        var returnData = "ReturnTest";
        return this.Request.CreateResponse(HttpStatusCode.OK, new { returnData });
    }

The problem is, i keep getting "404 not found" when posting.

I tried:

  1. all stack overflow answers

  2. online answers

  3. removing the content of the "Upload" function, and changing to MVC's Controller base class -> still same result.

  4. changing the name of "Upload" method to "Post" and posting to "/api/uploads" -> same 404.

Please help! thanks!

EDIT

this is the browser "Network" tab: 所有以前的帖子都成功了,只是上传失败了

  • I am using HTTPS

  • this was tested "live" (without localhost) = same result.

EDIT2

my routes:

  app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });

these are the only routes that are declared.

EDIT3

I am 100% sure the problem is me using " ApiController " as base class instead of " Controller ". i added a new controller and i can access it no problem. now just making it work as i don't have " Request.Content " in " Controller " - any ideas?

I see 2 possibilities to make it work:

  1. pass HttpRequestMessage as a parameter to the method:

    public async Task Post([FromBody]HttpRequestMessage request)

but i am getting HTTP 500 as i don't know how to pass from angular's POST.

or:

  1. get Request.Content to resolve under Controller (no idea how).

has someone managed to do this? thanks!

I was able to solve the problem i posted in EDIT3 by using:

 if (Request.Form.Files != null && Request.Form.Files.Count > 0)
        {
            var file = Request.Form.Files[0];
            var contentType = file.ContentType;

            using (var fileStream = file.OpenReadStream())
            {
                using (var memoryStream = new MemoryStream())
                {
                    await fileStream.CopyToAsync(memoryStream);
                    FileStream newFS = new FileStream(Settings.UserImagesDir + "\\name.png", FileMode.Create);
                    memoryStream.WriteTo(newFS);
                    newFS.Close();                     
                }
            }
        }

and all this in a regular web api controller that inherits from Controller .

thanks everyone for your help, although no one solved it you all pushed me in the right direction.

The problem is that your routing is misconfigured for the URL /api/Uploads/Upload . In order to make it match, you have to specify a template for the method Upload , since it is not actually named after an HTTP method.

[HttpPost("upload")]
public async Task<HttpResponseMessage> Upload()
{
    // code omitted...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM