2

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!

Selthien
  • 1,178
  • 9
  • 33
  • The check returns that because that's what you are inputting. You should be looking at check from your Web API controller and not from the client – Teja Jun 25 '20 at 16:11

2 Answers2

0

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);
Thangadurai
  • 2,573
  • 26
  • 32
0

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.

Teja
  • 305
  • 1
  • 6
  • I would prefer to pass it in the body. That is what I am trying to figure out. Ignore the first portion and look at my edit farther down. I changed my address to the correct one. – Selthien Jun 25 '20 at 16:15
  • If you want it in the body, you are already doing that in your POST call. The only thing you need to change is your Web API controller's action. You don't get a query string anymore. You'd have to read your body then. Do that and your API works just fine – Teja Jun 25 '20 at 16:23
  • If you check my edit I added the [From Body] tag but my api is still never reached and is timing out? I know for sure the localhost is correct its the same every time at this moment. This is more of a test of concept atm. – Selthien Jun 25 '20 at 16:26
  • Just looked at your edit. I can suggest two options: Use Postman or Fiddler to post a request to that URI with this body. If your API gets hit, then your MVC needs changes. Second, try using a simple data type like string as your body instead of that view model. – Teja Jun 25 '20 at 16:38
  • If I use a simple string how would I form the JSON for the post? That is kind of the part that is confusing me. It appears by using the view model it adds the appropriate modelToCreate: "my value". I will test with post man and see what is going on. – Selthien Jun 25 '20 at 16:39
  • I just read some other user complain that PostAsync sometimes ignores body and treats it as a GET request. Try debugging that specific line and validate if the content is not null – Teja Jun 25 '20 at 16:42
  • Thats the issue my debugger is never reaching the API. I verified using postman(I even tried accessing the default api/values code they add in and no matter what the request times out. I have both my MVC and web api project started. The localhost I am calling is correct, and I still get no response. – Selthien Jun 25 '20 at 16:52
  • Add a sample GET action and return some value. Check if you can get that data on Postman GET – Teja Jun 25 '20 at 17:04
  • I did and I cant for some reason. So I believe there may be a setup issue with my web api project. I can't reach anything while its hosted on localhost – Selthien Jun 25 '20 at 17:08
  • What's the fix? – Teja Jun 25 '20 at 17:28
  • A whole lot of learning from my end. But the main reason it was not reaching the break point is because my local host was https but my url was http. Pretty simple thing I completely overlooked. – Selthien Jun 25 '20 at 17:32