Reputation:
I am trying to send data to a API it works fine using Postman but I am not sure how to do it in code.
I created this method that is using test json string and it send the data in the body. When I debug it the error is coming from this line
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
and I get the message
The remote server returned an error: (400) Bad Request.' "
Any help will be great not sure what I am doing wrong.
public static T Post<T>(string httpMethod, string url, object model)
{
var fullUrl = apiUrl + url;
var json = "{\"FirstName\":\"1\",\"LastName\":\"1\"}";
string data = json;
Stream dataStream = null;
WebRequest Webrequest;
Webrequest = WebRequest.Create(fullUrl);
Webrequest.ContentType = "application/json";
Webrequest.Method = WebRequestMethods.Http.Post;
Webrequest.PreAuthenticate = true;
Webrequest.Headers.Add("Authorization", "Bearer Toeke n");
byte[] byteArray = Encoding.UTF8.GetBytes(data);
Webrequest.ContentLength = byteArray.Length;
dataStream = Webrequest.GetRequestStream();
using (dataStream = Webrequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
}
WebResponse response = Webrequest.GetResponse();
}
API
[HttpPost]
public IHttpActionResult SaveForm(RequestWeb Request)
Postman Raw
{
"FirstName": "1",
"LastName": "1",
}
Upvotes: 2
Views: 1823
Reputation: 74365
I'd recommend using Flurl. It's a "fluent" HTTP client that is short, sweet and elegant. Extensible, and testable, too.
It's [most] a bunch of extension methods along with a few helper classes that wrap the core .Net bits. Posting JSON to an API can be as simple as this (example from Flurl):
Person person = await "https://api.com"
.AppendPathSegment("person")
.SetQueryParams(new {
a = 1 ,
b = 2
})
.WithOAuthBearerToken("my_oauth_token")
.PostJsonAsync(new {
first_name = "Claire" ,
last_name = "Underwood"
})
.ReceiveJson<Person>();
Your use case might look something like this:
using Flurl;
using Flurl.Http;
. . .
private static async TResponseBody PostToSomeApi<TRequestBody,TResponseBody>(
string path,
TRequestBody requestBody
)
{
const string token = "this-is-my-oauth-bearer-token";
TResponseBody response = await
"https://my.special.urlcom/api/xyz"
.AppendPathSegment( path )
.WithOAuthBearerToken( token )
.AllowHttpStatus( "200" )
.PostJsonAsync( requestBody )
.ReceiveJsonAsync<TResponseBody>()
;
return response;
}
And you can get fancier if you need to inject logging or examine response headers, deal with cookies, etc.
Upvotes: 0
Reputation: 5715
Is there any specific reason for you using WebRequest
instead of HttpClient
? If you're not doing any FTP work and you're using .NET Framework 4.5+ or .NET Core you're better off migrating to HttpClient
as it gives you easier usage flow, comes with async support out of the box and is quite easier to mock and test, while giving you more functionality on top of that. Overall, it is the modern API for making requests from .NET.
public async Task<T> Post<T>(object model) // use actual model type instead of type object
{
var url = "Specify URL";
var token = "Specify Token";
var payload = JsonSerializer.Serialize(model);
// Preferably get the instance from dependency injection or hoist it as a private variable in the class body.
// In any case, don't recreate it like we're doing here.
var client = new HttpClient();
var requestMessage = new HttpRequestMessage(HttpMethod.Post, url);
requestMessage.Headers.Add("Authorization", $"Bearer {token}");
requestMessage.Content = new StringContent(payload, Encoding.UTF8, "application/json");
var responseMessage = await client.SendAsync(requestMessage);
if (responseMessage.IsSuccessStatusCode)
{
var result = await responseMessage.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<T>(result);
}
else
{
// Handle error result
throw new Exception();
}
}
Upvotes: 3
Reputation: 247561
If possible, consider using HttpClient
instead
Simplified example
//...Assuming an static HttpClient
static HttpClient client;
public static async Task<T> PostAsync<T>(string url, object model) {
var fullUrl = apiUrl + url;
//Assuming object model will be converted to JSON
string json = "{\"FirstName\":\"1\",\"LastName\":\"1\"}";
string data = json;
httpClient.DefaultRequestHeaders.Authorization = new HttpCredentialsHeaderValue("Bearer", "Token");
var content = new StringContent(data, Encoding.UTF8, "application/json");
HttpResponseMessage response = await httpClient.PostAsync(new Uri(fullUrl), content);
T resp = await response.Content.ReadAsAsync<T>();
return resp;
}
I would also suggest explicitly telling the Server to expect the data in the request body
[HttpPost]
public IHttpActionResult SaveForm([FromBody]RequestWeb Request)
Upvotes: 2