Joshua I
Joshua I

Reputation: 560

WebApi 2 call using HttpWebrequest/HttpClient

I need to make a webApi call to the controller from a C# code .Net 4.5

My Api controller looks like:

[Route("api/GetData/{id}/{createDate}")]
public List<DataModel> GetData(int id, DateTime createDate)
{
    var dataDb = new DataDb(SqlConnectionString);
    var result = dataDb .GetSalesData(id, createDate);
    return result;
}

How do i call the above controller using c#, I dont want to pass parameter in url for e.g. "http://wks337:8989/api/GetData/1/2013-06-11/12337" instead add it to header/body (any best approach) rather than Uri.

I tried using HttpWebRequest as:

string serviceUrl = url + methodName + "//";
dynamic parameterObj = new ExpandoObject();
parameterObj.id= definitionId;
parameterObj.createDate= jobDate;

string strParameter = JsonConvert.SerializeObject(parameterObj);

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceUrl);
request.ContentType = "application/json; charset=utf-8";
request.Method = "POST";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
    streamWriter.Write(parameters);
    streamWriter.Flush();
    streamWriter.Close();
}

var httpResponse = (HttpWebResponse)request.GetResponse();

But it always gets me 404 error. I know am doing something or entirely wrong, Could anyone guide me to the correct code.

I tried google but example suggested to pass parameter in Url which I dont want.

Upvotes: 1

Views: 13144

Answers (4)

amarnath chatterjee
amarnath chatterjee

Reputation: 1962

It is sometime quite difficult to understand the underlying issue. Catch the web exception and check the response object from server. It might reveal actual error underneath.

catch (WebException e)
        {
            using (WebResponse response = e.Response)
            {
                HttpWebResponse httpResponse = (HttpWebResponse) response;
                Console.WriteLine(httpResponse.StatusCode);
                using (Stream data = response.GetResponseStream())
                using (StreamReader reader = new StreamReader(data))
                {
                    string text = reader.ReadToEnd();
                    Console.WriteLine(text);
                }
            }
        }

Upvotes: 0

Eldho
Eldho

Reputation: 8281

You could try this

using HttpClient

 using (var client = new HttpClient())
 {
   //My Custom Class
   var request = new CreateAppRequest()
   {
      userAgent = "myAgent",
    
   };

   var response = await client.PostAsync("https://domain.com/CreateApp", 
    new StringContent(JsonConvert.SerializeObject(request), 
        Encoding.UTF8, "application/json")); 
 }

A Nuget package available, using httpclient and Newtonsoft

Install-Package Microsoft.AspNet.WebApi.Client

// HTTP POST
var gizmo = new Product() { Name = "Gizmo", Price = 100, Category = "Widget" };
response = await client.PostAsJsonAsync("api/products", gizmo);
if (response.IsSuccessStatusCode)
{
    // Get the URI of the created resource.
    Uri gizmoUrl = response.Headers.Location;
}

msdn reference

Upvotes: 1

strickt01
strickt01

Reputation: 4048

The route for your action specifies that the parameters are passed as part of the URL. If you wanted to ensure that the parameters are passed in the body then you'd need to decorate your method as such:

[Route("api/GetData")]
[HttpPost]
public List<DataModel> GetData(int id, DateTime createDate)
{
    var dataDb = new DataDb(SqlConnectionString);
    var result = dataDb .GetSalesData(id, createDate);
    return result;
}

also for calling the the api from c# HastyApi or RestSharp

Upvotes: 0

Preet Singh
Preet Singh

Reputation: 1861

the problem here is that your controller method is a Get[HttpGet] method and in your calling code

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceUrl);
request.ContentType = "application/json; charset=utf-8";
request.Method = "POST";

your are making a "POST" request. if you want the parameters to go in the request body rather than url. you would need to make your action method [HttpPost]. First create a model class that will bundle up your parameters as

public class GetDataParameters
{
  Public int Id {get; set;}, 
  public DateTime createDate {get; set;}
}

then in the controller

[Route("api/GetData/")]
[HttpPost]
public List<DataModel> GetData([FromBody] getDataParameters)
{
    var dataDb = new DataDb(SqlConnectionString);
    var result = dataDb .GetSalesData(getDataParameters.id, getDataParameters.createDate);
    return result;
}

now you should be able to make a post request by passing parameters in the body. Also as a suggestion instead of writing all that code your self for making requests have a look at HastyApi or even better RestSharp

Upvotes: 4

Related Questions