Calling Web API Post method from MVC 5 controller while passing single string parameter

Viewed 1646

So I am debugging my application and have a web API running along side my MVC application. I am simply trying to call a web API post method while passing a string parameter.

General Information:

  1. Using .NET Framework 4.5.2

  2. Want to send string parameter as JSON and receive HttpResponseMessage as JSON

WEB API ProjectController:

This is my web api method I am attempting to call.

[HttpPost]
    public HttpResponseMessage CreateStandardSchematic(string modelToCreate)
    {
        string check = _eplanConnectionService.CreateProject(modelToCreate, "");
        var NewProjectLog = new NewProjectLogDTO
        {
            ErrorMessage = check == "Success" ? "Success" : check,
            PassFail = check == "Success" ? "Pass" : "Fail",
            MaterialNumber = modelToCreate,
        };
        return Request.CreateResponse(System.Net.HttpStatusCode.OK, NewProjectLog);
    }

MVC Controller:

This is my MVC 5 project where I am simply trying to call the above web api method.

public JsonResult CreateStandardSchematics(List<MaterialViewModel> listOfMaterials, string clientId)
    {
        using (var client = new HttpClient())
        {
            //using JSON
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            var stringContent = new StringContent(listOfMaterials[0].Material);//passing material number as string

            //This is the portion I am unsure about. I see a lot of online suggestions saying 
            //to use PostAsJsonAsync but I do not have access to the libraries. I would prefer 
            //to use PostAsync() but am unsure how to format the correct query string I believe?
            var responseTask = client.PostAsync("http://localhost:44344/api/Project?modelToCreate=", stringContent);
            responseTask.Wait();

            var result = responseTask.Result;
            if (result.IsSuccessStatusCode)
            {
                var readTask = result.Content.ReadAsStringAsync().Result;
                //Deserialize object
                var deserialized = JsonConvert.DeserializeObject<List<NewProjectLogViewModel>>(readTask);
            }
            else //web api sent error response 
            {
                //log response status here..
            }
        }
        //Other stuff
    }

This is my first time trying to debug my web api and mvc project at the same time. If you have any suggestions on how to properly call an Asp.Net Web API Post method (with simple query string parameter) from an MVC 5 Web project please point me in the right direction.

EDIT

So After doing a little more looking around I realized by java script string was probably wrong as well. Here is what I have now.

public JsonResult CreateStandardSchematics(List<MaterialViewModel> listOfMaterials, string clientId)
    {
        try
        {
            using (var client = new HttpClient())
            {
                //using JSON
                string modelToCreate = "modelToCreate:" + listOfMaterials[0].Material;
                var stringContent = new StringContent(JsonConvert.SerializeObject(modelToCreate), //passing material number as string
                    UnicodeEncoding.UTF8, "application/json");
                var check = stringContent.ReadAsStringAsync().GetAwaiter().GetResult();

                //This is the portion I am unsure about. I see a lot of online suggestions saying 
                //to use PostAsJsonAsync but I do not have access to the libraries. I would prefer 
                //to use PostAsync() but am unsure how to format the correct query string I believe?
                var responseTask = client.PostAsync("http://localhost:44344/api/Project", stringContent);
                responseTask.Wait();

                var result = responseTask.Result;
                if (result.IsSuccessStatusCode)
                {
                    var readTask = result.Content.ReadAsStringAsync().Result;
                    //Deserialize object
                    var deserialized = JsonConvert.DeserializeObject<List<NewProjectLogViewModel>>(readTask);
                }
                else //web api sent error response 
                {
                    //log response status here..
                }
            }
        }
        catch (Exception ex)
        {

            //
        }
    }

The check returns the following which still seems wrong:

enter image description here

EDIT 2:

My API function looks like the following now: I am trying to post the data as body content not a query string. (I was confused in my first post). But now I have a better idea of whats going on. It appears that even with this current setup my debug break point in the web api is still not being reached and the post request times out.

[HttpPost]
    public HttpResponseMessage CreateSchematic([FromBody] MaterialViewModel modelToCreate)
    {
        string check = _eplanConnectionService.CreateProject(modelToCreate.Material, "");
        var NewProjectLog = new NewProjectLogDTO
        {
            ErrorMessage = check == "Success" ? "Success" : check,
            PassFail = check == "Success" ? "Pass" : "Fail",
            MaterialNumber = modelToCreate.Material,
        };
        return Request.CreateResponse(System.Net.HttpStatusCode.OK, NewProjectLog);
    }

This is now my MVC controller:

I simplified this quite so there isnt so much junk for everyone to look at. I started to use an object versus just a simple string called MaterialViewModel (see class below):

public JsonResult CreateStandardSchematics(List<MaterialViewModel> listOfMaterials, string clientId)
    {
        using (var client = new HttpClient())
        {
            //using JSON
            var stringContent = new StringContent(JsonConvert.SerializeObject(listOfMaterials[0]), //passing material number as string
                UnicodeEncoding.UTF8, "application/json");
            var check = stringContent.ReadAsStringAsync().GetAwaiter().GetResult();
            //This is the portion I am unsure about. I see a lot of online suggestions saying 
            //to use PostAsJsonAsync but I do not have access to the libraries. I would prefer 
            //to use PostAsync() but am unsure how to format the correct query string I believe?
            var responseTask = client.PostAsync("http://localhost:44344/api/Project", stringContent);
            responseTask.Wait();
            var result = responseTask.Result;
            if (result.IsSuccessStatusCode)
            {
                var readTask = result.Content.ReadAsStringAsync().Result;
                //Deserialize object
                var deserialized = JsonConvert.DeserializeObject<List<NewProjectLogViewModel>>(readTask);
            }
        }
    }

MaterialViewModel:

public class MaterialViewModel
{
    public string Material { get; set; }
}

my check now shows the following string being built before posting:

enter image description here

Thank you!

2 Answers

Normally an HTTP POST request assumes that the body of the request contains the parameters. In your case, if you want to pass the parameter by query string, you have to use [FromUri] attribute in the web API like below,

public HttpResponseMessage CreateStandardSchematic([FromUri]string modelToCreate)

To pass a valid string to the parameter, all you have to do is pass the value as a query string as below,

 var responseTask = client.PostAsync(String.Format("http://localhost:44344/api/Project?modelToCreate={0}",listOfMaterials[0].Material);

With little information that's posted, it's hard to pinpoint what's going on but I have some things to say that you can try.

  1. Looks like your POST method is not using any body, so you can convert it to a GET if that's alright for you.

  2. Remove hard-coded URI with a random port. It will change every now and then when you run/debug your Web API project. Set a static port in properties window if you want to hard code.

  3. This code is not really needed for you

    var check = stringContent.ReadAsStringAsync().GetAwaiter().GetResult();
    
  4. The way you are calling the POST URI is fine if that's not a query string parameter. If you want it to be a query string, your URI needs to reflect that.

Look at what ThangaDurai posted in his second line. Passing body is what you are doing now instead of query parameter.

Related