使用MVC和Web API进行Ng-File-Upload - 不断获取"404 Not Found"

tar*_*kil 5 c# asp.net-mvc angularjs

我需要允许在AngularJS + WebAPI项目中上传图像.实现这一点我根据以下示例代码使用ng-file-upload:http://monox.mono-software.com/blog/post/Mono/233/Async-upload-using-angular-file-upload-directive -and净的WebAPI服务/

对邮政编码进行一些调整,看起来像这样:

$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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经有很多web API控制器了,我根据上面链接中的代码示例添加了一个新的控制器(继承自System.web.http.ApiController而不是"常规" Microsoft.AspNet.Mvc.Controller类) :

 [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 });
    }
Run Code Online (Sandbox Code Playgroud)

问题是,我在发帖时不断发现"404 not found".

我试过了:

  1. 所有堆栈溢出答案

  2. 在线答案

  3. 删除"上传"功能的内容,并更改为MVC的Controller基类 - >仍然是相同的结果.

  4. 将"上传"方法的名称更改为"发布"并发布到"/ api/uploads" - >相同的404.

请帮忙!谢谢!

编辑

这是浏览器"网络"标签: 所有以前的帖子都成功了,只是上传失败了

  • 我正在使用HTTPS

  • 这是测试"实时"(没有localhost)=相同的结果.

EDIT2

我的路线:

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

这些是宣布的唯一路线.

EDIT3

我100%确定问题是我使用" ApiController "作为基类而不是" 控制器 ".我添加了一个新的控制器,我可以访问它没问题.现在只是让它工作,因为我没有" 控制器 "中的"Request.Content " - 任何想法?

我认为有两种可能性可以让它发挥作用:

  1. 将HttpRequestMessage作为参数传递给方法:

    public async Task Post([FromBody] HttpRequestMessage请求)

但我得到HTTP 500,因为我不知道如何从角度的POST传递.

要么:

  1. 获得Request.Content在Controller下解决(不知道如何).

有人设法这样做?谢谢!

tar*_*kil 2

我能够使用以下方法解决我在 EDIT3 中发布的问题:

 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();                     
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

所有这些都在继承自Controller 的常规 Web api 控制器中。

感谢大家的帮助,虽然没有人解决这个问题,但你们都把我推向了正确的方向。