AngularJS angular-file-upload无法将数据上传到WebAPI 2 CORS

时间:2015-01-25 23:06:14

标签: javascript angularjs file-upload asp.net-web-api cors

我正在尝试使用https://github.com/danialfarid/angular-file-upload将图片上传到其他域中的我的webAPI。

我的HTML:

<input 
    type="file" 
    ng-file-select="onFileSelect($files)"
    ng-model="imgData" 
    accept="image/*" 
    ng-click="test()" >

我的控制器:

app.controller('userController', [ 'removed', '$upload',
function (removed, $upload) {

    $scope.onFileSelect = function ($files) {
        console.log('onFileSelect');  // --------- THIS METHOD DOES NOT FIRE
        $http.post(serviceBase + 'api/person/image', data, {
            withCredentials: true,
            transformRequest: angular.identity
        }).success('ok').error('fail');
    }
    // tried different things from all the resources found online:
    $scope.test = function () {

        // THIS WORKS but how to get the file??
        // successfull call to controller method but unable to retrieve image file inside controller
        $http.post(serviceBase + 'api/person/image', data).then(function (response) {
            return response;
        });

        // unable to call controller method ('Resourse not found', CORS issue?)
        $scope.upload = $upload.upload({
            url: 'person/image', 
            headers: { 'Authorization': 'bearer placeHolderText' },
            file: $scope.imgData,
            ) };

        // unable to call controller method ('Resourse not found', CORS issue?)
        $http.post(serviceBase + 'api/person/image', data, {
            withCredentials: true,
            transformRequest: angular.identity
        }).success('ok').error('fail');}}

API控制器方法:

    [HttpPost()]
    [ActionName("image")]
    [ResponseType(typeof(JObject))]
    public async Task<IHttpActionResult> Postimage(HttpPostedFileBase file)
    {

**更新:启用CORS详细信息...(Microsoft.Owin.Cors)**

My Startup.cs:

  public void Configuration(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();

        ConfigureOAuth(app);

        WebApiConfig.Register(config);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(config);
    }

    public void ConfigureOAuth(IAppBuilder app)
    {
        //use a cookie to temporarily store information about a user logging in with a third party login provider
        app.UseExternalSignInCookie(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ExternalCookie);
        OAuthBearerOptions = new OAuthBearerAuthenticationOptions();

        OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions() {

            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
            Provider = new SimpleAuthorizationServerProvider(),
            RefreshTokenProvider = new SimpleRefreshTokenProvider()
        };

这很可能是一个CORS问题,因为我可以使用$ HTTP.Post发布到该控制器方法。我在服务器上启用了CORS。我已经阅读并尝试了两天,我已经碰到了一堵砖墙,非常感谢任何建议/建议。

更新2:

另一天的研究/试错:

我可以发布这个帖子:

        $scope.upload = $upload.upload({
            url: 'http://localhost:26264/api/person/image', //upload.php script, node.js route, or servlet url
            file: $scope.imgData,
            transformRequest: angular.identity,
            headers: { 'Content-Type': undefined }

但现在我得到'415(不支持的媒体类型)'..来自fiddler的详细信息:

“此资源不支持请求实体的媒体类型'multipart / form-data'。”,“exceptionMessage”:“没有MediaTypeFormatter可用于从媒体类型为'multipart的内容中读取'HttpPostedFileBase'类型的对象/格式数据”。“

1 个答案:

答案 0 :(得分:1)

我最终使用ng-flowImages Sample帮助您进行设置。 我还使用this来了解如何读取控制器中的数据,最后this来保存我的文件。最终解决方案:

控制器:

    [HttpPost()]
    [ActionName("image")]
    [ResponseType(typeof(JObject))]
    public async Task<IHttpActionResult> Postimage()
    {
        // Check if the request contains multipart/form-data.
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }

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

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

            // This illustrates how to get the file names.
            foreach (MultipartFileData file in provider.FileData)
            {
                //Console.WriteLine(file.Headers.ContentDisposition.FileName);
                //Trace.WriteLine("Server file path: " + file.LocalFileName);
                if (File.Exists(Path.Combine(root, "test.jpg")))
                    File.Delete(Path.Combine(root, "test.jpg"));

                File.Move(file.LocalFileName, Path.Combine(root, "test.jpg"));
                return Ok();
            }
        }
        catch (System.Exception e)
        {
        }
        return Ok();
    }

角:

app.config(['flowFactoryProvider', function (flowFactoryProvider) {
    flowFactoryProvider.defaults = {
        target: 'myURL',
        permanentErrors: [404, 500, 501],
        maxChunkRetries: 1,
        chunkRetryInterval: 5000,
        simultaneousUploads: 4,
        singleFile: true
    };
    flowFactoryProvider.on('catchAll', function (event) {
        console.log('catchAll', arguments);
    });
    // Can be used with different implementations of Flow.js
    // flowFactoryProvider.factory = fustyFlowFactory;
}]);

HTML:

<div class="form-horizontal" role="form" flow-init
   flow-file-added="!!{png:1,gif:1,jpg:1,jpeg:1}[$file.getExtension()]"
   flow-files-submitted="$flow.upload()">

<span class="btn-success" flow-btn>Upload Image</span>
</div>