kkdeveloper7
kkdeveloper7

Reputation: 565

AngularJS HTTP POST using ng-file

I can't seem to get this working with ng-file upload. I need to pass in fine in my controller with bridge Id

The error I'm getting is:

"{"Message":"No HTTP resource was found that matches the request URI 
'http://localhost/api/BridgeController/'.","MessageDetail":"No type was 
found that matches the controller named 'BridgeController'."}"

Can't figure out why it can't find my method. Any ideas?

Here is my controller code that will get moved into a service

$scope.uploadFile = function (file) {
    console.log("hitting file upload", $scope.selectedBridge);
    if (file) {
        debugger;

        var request = {
            method: 'POST',
            url: '/api/Bridge/UploadBridgeImage',
            data: angular.toJson($scope.selectedBridge.BridgeID),
            file: file,
            headers: { 'Content-Type': undefined }
        };

        Upload.upload(request).then(function (response) {

        });
    }
}

and back end C#

[HttpPost]
[Route("api/Bridge/UploadBridgeImage")]
public IHttpActionResult UploadBridgeImage()
{
    try
    {
        var uploadedFiles = HttpContext.Current.Request.Files;

        for (int i = 0; i < uploadedFiles.Count; i++)
        {
            var fileToSave = uploadedFiles[i];

            var fileBytes = _iStremHelper.GetBytes(fileToSave.InputStream, fileToSave.ContentLength);
            var file = BridgeFileEntity(fileBytes, fileToSave, 1);

            using (_iFileRepository)
            {
                _iFileRepository.Save(file);
            }
        }
        return Ok();
    }
    catch (Exception ex)
    {
        return InternalServerError();
    }
}

Edited Code Here. I was able to hit my break point in that post method in my C# controller. File have all the data I need. Now I need to get "data" some how. Any idea where is it located in context?

Upvotes: 3

Views: 270

Answers (1)

Aleksey L.
Aleksey L.

Reputation: 37988

In order to get both file stream (in memory) and additional json data in web api controller you can define custom MultipartStreamProvider:

class MultipartFormDataInMemoryStreamProvider : MultipartFormDataRemoteStreamProvider
{
    public override RemoteStreamInfo GetRemoteStream(HttpContent parent, HttpContentHeaders headers)
    {
        return new RemoteStreamInfo(new MemoryStream(), string.Empty, string.Empty);
    }
}

Then use it in controller:

public async Task<IHttpActionResult> UploadBridgeImage()
{
    var provider = await Request.Content.ReadAsMultipartAsync(new MultipartFormDataInMemoryStreamProvider());
    foreach (var httpContent in provider.Contents)
    {
        if (!string.IsNullOrEmpty(httpContent.Headers.ContentDisposition?.FileName))
        {
            var byteArray = await httpContent.ReadAsByteArrayAsync();
            //do whatever you need with byteArray
        }
    }

    var bridgeId = provider.FormData["bridgeId"];

    return Ok();
}

And on client side:

var request = {
    url: '/api/Bridge/UploadBridgeImage',
    data: {
        file:file,
        bridgeId:$scope.selectedBridge.BridgeID
    }
};

Upload.upload(request).then(function (response) {

});

Upvotes: 1

Related Questions