2

I am trying to consume/call an MVC Web API controller method, which will be used to upload a file. I am struggling to call it from my MVC controller.

Here's my code for the API Controller

public class ImportController : ApiController
{
    [HttpPost]
    public bool PutImportFile(byte[] fileToBeImported, string nameOfTheFileToBeImported)
    {   
        // I am doing file saving stuff here             
    }
}

I have tested the file saving part by changing the method to HttpGet and its working when I called it directly from the browser. I removed the parameters for that.

However, I am not able to figure out how to call it from a client.

I have tried below.

public class ImportFileModel
{
    public byte[] FileToBeImported { get; set; }

    public string NameOfTheFileToBeImported { get; set; }
}

The below code will accept a file from the browser uploaded by user and post it to the API controller to save the file.

[HttpPost]
public async Task<JsonResult> Upload()
{
    byte[] file;
    string fileName = string.Empty;

    if (Request.Files.Count > 0)
    {
        try
        {
            fileName = Request.Files[0].FileName;

            using (MemoryStream ms = new MemoryStream())
            {
                Request.Files[0].InputStream.CopyTo(ms);
                file = ms.ToArray();
            }

            //To do: get url from configuration
            string url = "http://localhost:(port)/api/Import/PutImportFile";

            using (HttpClient client = new HttpClient())
            {
                client.BaseAddress = new Uri(url);
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/bson"));

                ImportFileModel request = new ImportFileModel
                {
                    FileToBeImported = file,
                    NameOfTheFileToBeImported = fileName
                };

                MediaTypeFormatter bsonFormatter = new BsonMediaTypeFormatter();
                var result = await client.PostAsync(url, request, bsonFormatter);

                HttpResponseMessage response = result.EnsureSuccessStatusCode();
            }
        }
        catch (Exception ex)
        {
            // exception handling here
        }
    }

    return Json(true, JsonRequestBehavior.AllowGet);
}

It ends up in an exception at the last line.

HttpResponseMessage response = result.EnsureSuccessStatusCode();

Throwing 404 not found error.

I have also tried the same from a console application using HttpWebRequest. It also throws the same error.

2
  • 1
    Try to define route explicitly, may be that works. Commented Mar 29, 2017 at 6:50
  • @MUT I believe, you are right. As it worked after making the parameters bundle into a single object. I will also try and make an explicit route definition and see if it works that way as well. But I wonder, how it works in normal MVC controllers without defining explicit routes and not in Web API controllers. Commented Mar 29, 2017 at 6:53

1 Answer 1

2

Your Web API method PutImportFile is setup to receive two values, not a single model; hence, your HttpClient call is not recognized (no matching route found). Change your Web API method to receive a model:

public class ImportController : ApiController
{
    [HttpPost]
    public bool PutImportFile(ImportFileModel fileInfo)
    {   
        //Your code to save the file...            
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Tried this but it still does not reach the method. Error type has changed from 404 to 500, however, it doesn't reach the controller.
Interesting, it looks like the method is found then, but something goes wrong. If you breakpoint at the entry to the method, does it hit?
It worked!!! I had added a section in web config from other questions from SO. <modules runAllManagedModulesForAllRequests="true" /> in <system.webServer>. Removed it and it worked! Thanks a ton! Never thought it would be routing issue.
Awesome! Test it from the browser too - you may need to make a change to how JSON is being sent in, since the method is expecting a single object now.
Luckily, that part is still pending to write; so I will work on sending a single JSON object. You made my day! Cheers!

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.