3

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?

14
  • Is attribute routing enabled in web api? Commented Jun 20, 2016 at 5:06
  • Try and rename the route to "api/Bridge/UploadBridgeImage" in both client and route-attribute. The default way is not to name the controller by sufix controller. Commented Jun 20, 2016 at 5:41
  • @AlekseyL. yes they are enable config.MapHttpAttributeRoutes(); Commented Jun 21, 2016 at 3:09
  • @MarcusH tried your suggestion getting same error message. Commented Jun 21, 2016 at 3:13
  • @kkdeveloper7 another routes are working? Are you sure your dev port is 80? (maybe localhost:portNumber) Commented Jun 21, 2016 at 4:25

1 Answer 1

1

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) {

});
Sign up to request clarification or add additional context in comments.

5 Comments

thank you i will try that. the only thing i dont understand is where do i use this 'MultipartStreamProvider'
in web api controller - see example
ohh, sorry i missed that new line
This worked for me Thank you so much!!! Couple questions though, 1. provider.Content gives me the count of 2 because i have file and bridge Id coming in. Is there a way for me to separate this only for file and not have Id in that Content? and if no why is it like this?
It is because multipart content contains two parts: file + bridgeId. You can identify file content by checking if file name exists in content disposition header. see updated answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.