在 Web Api 和 AngularJS 中上传文件和表单数据

8
我正在遵循这个博客中的指南,学习如何发布表单数据和文件。我正在尝试将文件上传到服务器上的目录,但是以下操作没有生效。
这是提交函数:
[HttpPost]
        public async Task<HttpResponseMessage> UploadFile(HttpRequestMessage request)
        {
            String root = HttpContext.Current.Server.MapPath("~/Logo/");

            if (!request.Content.IsMimeMultipartContent())
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }

            var data = await Request.Content.ParseMultipartAsync();
            var httpRequest = HttpContext.Current.Request;

            if (data.Files.ContainsKey("file"))
            {

                var file = data.Files["file"].File;      // this is getting the file
                var fileName = data.Files["file"].Filename; // this is getting the fileName
               // System.Web.HttpPostedFile filePost = data.Files["file"];
                String a = root + "" + Path.GetFileName(fileName);
                string b = a;
                var postedFile = fileName;                                                  // this is not working
                var filePath = HttpContext.Current.Server.MapPath("~/Logo/" + fileName);    // can someone help please 
                postedFile.SaveAs(filePath);                                                // I

            }

            if (data.Fields.ContainsKey("description"))
            {
                var description = data.Fields["description"].Value;
            }

            return new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent("Thank you for uploading the file...")
            };
        }

如何将文件保存到服务器目录中?
5个回答

7

目前我正在使用以下代码上传图像文件,但它也适用于任何类型的文件:

public string UploadImage()
    {
        HttpRequestMessage request = this.Request;
        if (!request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(new HttpResponseMessage((HttpStatusCode.UnsupportedMediaType)));
        }
        var context = HttpContext.Current.Request;
        if (context.Files.Count > 0)
        {
            var resourcePhoto = new PhotoHelper(HttpContext.Current.Server.MapPath("~"));
            var file = context.Files.AllKeys.FirstOrDefault();
            var result = resourcePhoto.SaveResourceImage(context.Files[file], User.Identity.Name);
            return result;
        }
        else
        {
            return null;
        }
    }

SaveResourceImage 方法中,我执行以下操作:

 postedFile.SaveAs(resultPath);

这就是它。


5

服务

app.factory('myService', ['$http', function ($http) {
    return {
        uploadFile: function(url, file) {
            return $http({
                url: url,
                method: 'POST',
                data: file,
                headers: { 'Content-Type': undefined }, //this is important
                transformRequest: angular.identity //also important
            });
        },
        otherFunctionHere: function(url, stuff) {
            return $http.get(url);
        }
    };
}]);

控制器

app.controller('MainCtrl', ['$scope', 'myService', function($scope, myService) {

    $scope.uploadFile = function() {
        var fileInput = document.getElementById('fileInput');
        fileInput.click();

        //do nothing if there's no files
        if(fileInput.files.length === 0) return;

        var file = fileInput.files[0];

        var payload = new FormData();
        payload.append("stuff", "some string");
        payload.append("file", file);

        //use the service to upload the file
        myService.uploadFile('/path/to/API', payload).then(function(response){
            //success, file uploaded
        }).catch(function(response){
            //bummer
        });
    }

}]);

C# 控制器

[HttpPost]
public JsonResult UploadFile(string stuff, HttpPostedFileBase file)
{
    string fileName = Path.GetFileNameWithoutExtension(file.FileName);
    string extension = Path.GetExtension(file.FileName);

    //save the file
    try
    {
        file.SaveAs('somePath' + fileName + extension);
    }
    catch (IOException exc)
    {
        return Json(new { status = 'error', message = exc.Message });
    }

    return Json('horray');
}

你救了我的一天!只有在将Content-Type设置为未定义时,Ajax post才会为FormData设置正确的Content-Type头! - Yura
这只能接受一个文件,对吗?你如何修改它以接受多个文件? - big_water

0

我曾经在Angular 1.5上尝试过这种方法。因此,我有前端控制器和存储库。我没有将它保存在本地驱动器中。但是有一个缓冲区,我们可以将其保存在任何想要的地方。

控制器:

function submit() {

        modelTemplateRepository.add(model.modelTemplate, model.file)
            .then(function(response) {
                if (response && response.status) {
                    if (response.status === 422) {
                        model.apiError = response.data;
                        model.isSubmitting = false;
                    }
                    else {
                        onSaved(response.data);
                    }
                }
            });
    }

代码库:

function add(modelTemplate, file) {

        var fd = new FormData();

        fd.append('file', file);
        fd.append('modelTemplate',angular.toJson(modelTemplate));

        return $http.post(config.ApiEndpoint + '/modeltemplate', fd,
        {
            transformRequest: angular.identity,
            headers: {'Content-Type': undefined}
        })
            .then(addComplete)
            .catch(function(data) {
                return angular.fromJson(data);
            });

        function addComplete(response, status, headers, config) {
            return response;
        }
    }

API:

[HttpPost]
    [Route("api/modeltemplate")]
    public async Task<IHttpActionResult> Post()
    {

        if (!Request.Content.IsMimeMultipartContent())
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);

        var provider = new MultipartMemoryStreamProvider();

        await Request.Content.ReadAsMultipartAsync(provider);

        var file = provider.Contents.First(x => x.Headers.ContentDisposition.Name == "\"file\"");

        var filename = "";
        var buffer = new byte[0];

        if (file.Headers.ContentDisposition.FileName != null)
        {
            filename = file.Headers.ContentDisposition.FileName.Trim('\"');
            buffer = await file.ReadAsByteArrayAsync();
        }

        var formContent = provider.Contents.First(x => x.Headers.ContentDisposition.Name == "\"modelTemplate\"");
        Task<string> stringContentsTask = formContent.ReadAsStringAsync();
        var stringContents = stringContentsTask.Result;
        var dto = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(stringContents);

        var result = ApiHelper.Add<dynamic>("modeltemplate", dto);

        return Ok(result);
    }

0

我能够使用这个片段调整代码,它就解决了问题

 var httpPostedFile = HttpContext.Current.Request.Files["file"];                                                 // this is not working
                var filePath = HttpContext.Current.Server.MapPath("~/Logo/" + fileName);    // can someone help please 
                httpPostedFile.SaveAs(filePath);

-1

要将文件保存到服务器上,您可以利用MultipartFormDataStreamProvider。而且我认为您不需要将请求作为参数之一传递。

string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);

然后可以获取文件的句柄

// Read the form data.
        await Request.Content.ReadAsMultipartAsync(provider);

        // This illustrates how to get the file names.
        foreach (MultipartFileData file in provider.FileData)
        {
            Trace.WriteLine(file.Headers.ContentDisposition.FileName);
            Trace.WriteLine("Server file path: " + file.LocalFileName);
        }
        return Request.CreateResponse(HttpStatusCode.OK);

这个ASP.NET页面提供了如何实现它的很好的概述。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接