500 Server Error when calling REST API over HTTPS - c#

I'm using this code to POST XML to a REST webservice, but am just getting a vague '500 Server Error'. If I paste the same XML into Fiddler it works perfectly, so what am I doing wrong?
using (var client = new HttpClient())
{
var httpContent = new StringContent(doc.ToString(), Encoding.UTF8, "text/xml");
var response = client.PostAsync(new Uri("httpsapiurl"),httpContent).Result;
if (response.IsSuccessStatusCode)
{
// EDITED: this isn't hit as IsSuccessStatusCode is always false
//Stream stream = await response.Content.ReadAsStreamAsync();
}
}

Could it be that you need to set the Content type on the request?
try
{
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, URL);
req.Content = new StringContent(doc.ToString(), Encoding.UTF8, "text/xml");
await httpClient.SendAsync(req).ContinueWith(async respTask =>
{
Debug.WriteLine(req.Content.ReadAsStringAsync());
};
}
catch (Exception ex)
{
}
Especially this line is important. I had similar problem with an API that refused to spit anything back when not setting the Content-Type header correct.
req.Content = new StringContent(doc.ToString(), Encoding.UTF8, "text/xml");
Don't know if it can help.

Related

ASP.NET Web API post to an external api

I would like to ask if it is possible for a created ASP.NET Web API (written in C#) to post to an external API?
If it is possible, please share sample code that can post to an url with adding headers and receive a callback from the external API.
A simple way to make HTTP-Request out of a .NET-Application is the System.Net.Http.HttpClient (MSDN). An example usage would look something like this:
// Should be a static readonly field/property, wich is only instanciated once
var client = new HttpClient();
var requestData = new Dictionary<string, string>
{
{ "field1", "Some data of the field" },
{ "field2", "Even more data" }
};
var request = new HttpRequestMessage() {
RequestUri = new Uri("https://domain.top/route"),
Method = HttpMethod.Post,
Content = new FormUrlEncodedContent(requestData)
};
request.Headers // Add or modify headers
var response = await client.SendAsync(request);
// To read the response as string
var responseString = await response.Content.ReadAsStringAsync();
// To read the response as json
var responseJson = await response.Content.ReadAsAsync<ResponseObject>();
Essentially you need use an instance of HttpClient to send an HttpRequestMessage to an endpoint.
Here is an example to post some jsonData to someEndPointUrl:
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, someEndPointUrl);
request.Headers.Accept.Clear();
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent(jsonData, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request, CancellationToken.None);
var str = await response.Content.ReadAsStringAsync();
if (response.StatusCode == HttpStatusCode.OK)
{
// handle your response
}
else
{
// or failed response ?
}

c# postasync returns unauthorized

I have the following code. It is returning a 401 Unauthorized although it works perfectly on PostMan.
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", string.Format("Bearer {0}", token));
var data1 = new { fName = "Sam", lName = "F" };
var result = await client.PostAsync(url, new StringContent(data1.ToString(), Encoding.UTF8, "application/json"));
var response = result.ToString();
What could be wrong here in the above code?
Start adding headers as they appear in Postman, one-by-one to your request.
One or more of them is what you're missing.
You can also use Fiddler to verify that how you think your request looks like, is how it actually looks like.
you can try this
var contentType = new MediaTypeWithQualityHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(contentType);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var json = JsonConvert.SerializeObject(data1);
var contentData = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url,contentData);
if it is not working, then you have problem with roles. Your API must be have a role authorization too, not just a token.

Process XML message using PostAsync from IHttpClientFactory

I had a problem to process soapEnvelopeXml document using PostAsync method from IHttpClientFactory.
This is what I was trying to do :
var soapEnvelopeXml = ObjectToXMLDocumentConverter.ObjectAsXmlDocument(object);
var content = new StringContent(soapEnvelopeXml.ToString(), Encoding.UTF8, "text/xml");
var response = await client.PostAsync(endpoint, content);
This was producing 400 Bad Request error.
What I find as a solution to my problem is direct usage of SOAP string instead of first converting it to XML message :
var soapString = ObjectToSoapRequestConverter.ObjectSoapStringRequest(object);
using (var client = clientFactory.CreateClient())
{
client.DefaultRequestHeaders.Add(...);
client.DefaultRequestHeaders.Add(...);
var content = new StringContent(soapString, Encoding.UTF8, "text/xml");
using (var response = await client.PostAsync(endpoint, content))
{
var soapResponse = await response.Content.ReadAsStringAsync();
...
}
}

How to convert C# RestSharp to C# ASP.NET httpclient

below codes is the generated c# restsharp codes from postman. How can I convert it to c# asp.net mvc4 codes for httpclient. When trying to debug in VS, I always have error of bad request. This is for ebay api creating a shipping fulfillment. Tested in postman works with the codes below.
var client = new RestClient("https://api.ebay.com/sell/fulfillment/v1/order/23-00000-11313/shipping_fulfillment");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Content-Language", "en-US");
request.AddHeader("Accept-Language", "en-US");
request.AddHeader("Accept-Charset", "utf-8");
request.AddHeader("Accept", "application/json");
request.AddHeader("Authorization", "Bearer v^1.1#i^1#I^3#f^0#p^3#r^0#t^H4sIAAAAA==");
request.AddParameter("application/json", "{\"lineItems\":[{\"lineItemId\":\"10022882297723\",\"quantity\":1}],\"shippedDate\":\"2020-02-11T01:28:16.475Z\",\"shippingCarrierCode\":\"Couriers Please\",\"trackingNumber\":\"UHV3436755010009000000\"}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
Current codes in asp.net but having error bad request.
private HttpClient CreateHttpClient()
{
var client = new HttpClient();
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
string baseAddress = WebApiBaseAddress;
if (string.IsNullOrEmpty(baseAddress))
{
throw new HttpRequestException("There is no base address specified in the configuration file.");
}
client.Timeout = new TimeSpan(0, 5, 59);
client.BaseAddress = new Uri(baseAddress);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Add("Authorization", string.Format("Bearer {0}", _cred.eBayToken));
client.DefaultRequestHeaders.Add("Accept-Language", "en-US");
client.DefaultRequestHeaders.Add("Accept-Charset", "utf-8");
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("LegacyUse", "true");
return client;
}
public HttpResponseMessage PostHttpResponse(string requestUri, object data)
{
var stringPayload = JsonConvert.SerializeObject(data);
var httpContent = new StringContent(stringPayload, Encoding.UTF8, "application/json");
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
httpContent.Headers.Add("Content-Language", "en-US");
httpContent.Headers.Add("Content-Encoding", "gzip");
using (var client = CreateHttpClient())
{
try
{
HttpResponseMessage response = client.PostAsJsonAsync(requestUri, httpContent).Result;
if (response.IsSuccessStatusCode)
{
return response;
}
else
{
GetErrorsResponse(response);
throw new HttpRequestException(string.Format("There was an exception trying to post a request. response: {0}", response.ReasonPhrase));
}
}
catch (HttpRequestException ex)
{
throw ex;
//return null;
}
}
}
Thank in advance for the help. It is very much appreciated.

How to pass request content with HttpClient GetAsync method in c#

How do I pass request content in the HttpClient.GetAsync method? I need to fetch data depending upon request content.
[HttpGet]
public async Task<HttpResponseMessage> QuickSearch()
{
try
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
HttpResponseMessage response =await client.GetAsync("http://localhost:8080/document/quicksearch");
if (response.IsSuccessStatusCode)
{
Console.Write("Success");
}
If you are using .NET Core, the standard HttpClient can do this out-of-the-box. For example, to send a GET request with a JSON body:
HttpClient client = ...
...
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("some url"),
Content = new StringContent("some json", Encoding.UTF8, ContentType.Json),
};
var response = await client.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
If you want to send content, then you need to send it as query string (According to your API route)
HttpResponseMessage response =await client.GetAsync("http://localhost:8080/document/quicksearch/paramname=<dynamicName>&paramValue=<dynamicValue>");
And in API check for "paramName" and "paramValue"
this works for me:
using (var httpClient = new HttpClient())
{
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("your url"),
Content = new StringContent("your json", Encoding.UTF8, ContentType.Json),
};
using (var response = await httpClient.SendAsync(request))
{
string apiResponse = await response.Content.ReadAsStringAsync();
}
}
EDITED:
This is minor different then #SonaliJain answer above:
MediaTypeNames.Application.Json instead of ContentType.Json
I'm assuming that your "request content" would be POST data, no?
If you're sending it using the standard form content way of doing it, you would first have to build the content:
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("username", "theperplexedone"),
new KeyValuePair<string, string>("password", "mypassword123"),
});
And then submit it using PostAsync instead:
var response = await client.PostAsync("http://localhost:8080/document/quicksearch", content);
Hi all thank you for your comments, i got the solution
[HttpGet]
public async Task<HttpResponseMessage> QuickSearch(HttpRequestMessage Query)
{
Debugger.Launch();
try
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
Console.WriteLine(Query);
HttpResponseMessage response = await client.GetAsync("http://localhost:8080/document/quicksearch/"+ Query.RequestUri.Query);
if (response.IsSuccessStatusCode)
{
Console.Write("Success");
}
else
{
Console.Write("Failure");
}
return response;
}
}
catch (Exception e)
{
throw e;
}

Categories

Resources