Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm trying to use https://github.com/danialfarid/angular-file-upload to upload an image to my webAPI in a different domain.

My HTML:

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

My Controller:

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 Controller Method:

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

**Update: Enabling CORS details... (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()
        };

It is most likely that this is a CORS issue because I can post to that controller method using $HTTP.Post. I have enabled CORS on server. I have been reading and trying things for two days and I've hit a brick wall, any suggestions/recommendations are greatly appreciated.

Update 2:

Another day of research/trial and error:

I can get this to post:

        $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 }

but now I get '415 (Unsupported Media Type)'.. details from fiddler:

"The request entity's media type 'multipart/form-data' is not supported for this resource.","exceptionMessage":"No MediaTypeFormatter is available to read an object of type 'HttpPostedFileBase' from content with media type 'multipart/form-data'."

share|improve this question
2  
How did you enable cors? Did you install the nuget package Microsoft.AspNet.WebApi.Cors, add config.EnableCors(); in webapi config and then add [EnableCors(origins: "http://mywebclient.azurewebsites.net", headers: "*", methods: "*")] to the controller? –  Wayne Ellery Jan 25 at 23:26
    
I am using Microsoft.Owin.Cors so I don't have [EnableCors(origins: "mywebclient.azurewebsites.net";, headers: "", methods: "")] available to me. I am so stuck, please help!! –  OverMars Jan 27 at 16:26

1 Answer 1

up vote 0 down vote accepted

I ended up using ng-flow, the Images Sample helped in getting setup. I also used this to find out how to read the data in my controller, and finally this to save my file. Final solution:

Controller:

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

Angular:

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>
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.