Expecting JSON/XML data in Webapi - c#

when i request one webapi request, i got error like Expecting JSON/XML data
try
{
string oRequest = _xml.UpdateInvereqxml(UserName, Password,OTAhotelid, Invy);
string uri = #"service/update";
System.Net.WebRequest req = System.Net.WebRequest.Create(uri);
req.Method = "POST";
req.ContentType = "text/xml";
System.IO.StreamWriter writer = new System.IO.StreamWriter(req.GetRequestStream());
writer.WriteLine(oRequest);
writer.Close();
System.Net.WebResponse rsp = req.GetResponse();
Stream istrm = rsp.GetResponseStream();
string StreamReader = new StreamReader(istrm).ReadToEnd();
}

I suggest using HttpClient to communicate with ASP.NET Web API. The class provides many functions for working with REST service (example)
public EnumProduct Post(EnumProduct product)
{
HttpResponseMessage reponse = httpClient.PostAsJsonAsync("api/enumproducts/Post", product).Result;
if (reponse.IsSuccessStatusCode)
{
var enumProduct = reponse.Content.ReadAsAsync().Result;
return enumProduct;
}
else
return null;
}

Related

Creating a webservice that needs input parameters

So, basically I am creating a Windows Service that is going to consult a SOAP Service and after that return an item. To find that item, who made the service created 2 "filters". customerFilter and itemFilter.
So, when I create the web request I need to insert thoose 2 parameters.
I have this:
static string date = DateTime.Now.Date.ToString("yyyy_MM_dd");
static string pathLog = "Logs/LogGetSalesLineDiscount/" + date + "LogGetSalesLineDiscount.txt";
public static string[] CallWebService(IOrganizationService service)
{
var action = "http://...";
var url = "http://...";
var request = (HttpWebRequest)WebRequest.Create(url);
var postData = "customerFilter=" + Uri.EscapeDataString("TESTE");
postData += "&itemFilter=" + Uri.EscapeDataString("TESTE");
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "text/xml;charset=\"utf-8\"";
request.Headers.Add("SOAPAction", action);
request.ContentLength = data.Length;
request.Accept = "text/xml";
request.Credentials = new NetworkCredential("...", "...");
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
using (System.IO.StreamWriter file = new System.IO.StreamWriter(AppDomain.CurrentDomain.BaseDirectory + pathLog, true))
{
file.WriteLine(responseString);
}
return null;
}
}
If I have that, it will return an error 500. I donĀ“t know why.
If I remove the action, it will return something about all the actions in the service...
Please help me, I dont know what to do....

How to pass header and Body value using HttpWebRequest in C#?

Im trying to POST API credentials data to API through HttpWebRequest class in C#, like i have to pass "Content-Type:application/x-www-form-urlencoded" in Header, then have to pass "grant_type:client_credentials,client_id:ruban123,client_secret:123456" in Body to get response/token (as described in API reference).
Bellow i attached work which i did
public class DataModel
{
public string grant_type { get; set; }
public string client_id { get; set; }
public string client_secret { get; set; }
}
static void Main(string[] args)
{
try
{
DataModel dm = new DataModel();
dm.grant_type = "client_credentials";
dm.client_id = "ruban123";
dm.client_secret = "123456";
var credentials = dm.grant_type + dm.client_id + dm.client_secret;
#region Http Post
string messageUri = "https://sampleurl.apivision.com:8493/abc/oauth/token";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(messageUri);
request.Headers.Add("Authorization", "Basic " + credentials);
request.ContentType = "application/json";
request.Method = "POST";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
string jsonModel = Newtonsoft.Json.JsonConvert.SerializeObject(dm);
streamWriter.Write(jsonModel);
streamWriter.Flush();
streamWriter.Close();
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
string jsonString = null;
using (StreamReader reader = new StreamReader(responseStream))
{
jsonString = reader.ReadToEnd();
Console.WriteLine();
reader.Close();
}
#endregion Http Post
}
catch (Exception ex)
{
}
}[API REFERENCE][1]
Here is correct HttpWebRequest using:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(pathapi);
request.Method = "POST";
string postData = "grant_type=client_credentials&client_id=ruban123&client_secret=123456";
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] bytes = encoding.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = bytes.Length;
Stream newStream = request.GetRequestStream();
newStream.Write(bytes, 0, bytes.Length);
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
HttpWebRequest approach is not relevant. Look at this question Setting Authorization Header of HttpClient
It looks like you missed setting of ContentLength property of HttpWebRequest. It should be equal number of bytes to send.
Se this link for more information:
https://learn.microsoft.com/en-us/dotnet/api/system.net.httpwebrequest.contentlength?view=netframework-4.8

Getting The remote server returned an error: (504) Gateway Timeout for WebAPI

I am using below code to make an API call from my C# code with WebRequest:
public object GetData()
{
object response = "";
string token = "EF232354";
string baseUrl = ConfigurationManager.AppSettings["BaseURL"].ToString();
string endPoint = ConfigurationManager.AppSettings["EndPoint"].ToString();
var httpWebRequest = (HttpWebRequest) WebRequest.Create(baseUrl + endPoint);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = HttpVerb.GET.ToString();
httpWebRequest.Headers.Add("token", token);
var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse();
Stream dataStream = httpResponse.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
using(JsonReader sdr = new JsonTextReader(reader))
{
JsonSerializer serializer = new JsonSerializer();
response = serializer.Deserialize(sdr);
}
return response;
}
Sometimes I am getting:
Message: The remote server returned an error: (504) Gateway Timeout.
Exception Type: System.Net.WebException
And how many requests can WebRequest make at a time?
I was adapting the question to demonstrate reading to a memory stream, when I noticed that the response was not being disposed. This is 95% likely to be your underlying problem. Streams and StreamReaders are also disposable and should be wrapped with using() closures.
public object GetData()
{
object response = "";
string token = "EF232354";
string baseUrl = ConfigurationManager.AppSettings["BaseURL"].ToString();
string endPoint = ConfigurationManager.AppSettings["EndPoint"].ToString();
var httpWebRequest = (HttpWebRequest) WebRequest.Create(baseUrl + endPoint);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = HttpVerb.GET.ToString();
httpWebRequest.Headers.Add("token", token);
using (var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse())
{
using (Stream dataStream = httpResponse.GetResponseStream())
{
using (StreamReader reader = new StreamReader(dataStream))
{
using(JsonReader sdr = new JsonTextReader(reader))
{
JsonSerializer serializer = new JsonSerializer();
response = serializer.Deserialize(sdr);
}
return response;
}
}
httpResponse.Close(); // For good measure. *should* be covered by Dispose.
}
}

HttpWebRequest.getResponse() returning NULL

I am attempting to create a console app that sends a WebRequest to a website so that I can get some information back from it in JSON format. Once I build up the request and try to get response I just want to simply print out the data, but when I call httpWebRequest.getResponse() it returns NULL.
I have tried multiple other methods of sending the data to the the url but those are all giving me like 404, or 400 errors, etc. This method at least isn't giving me any error, just a NULL.
Here is a snapshot of the documentation I am using for the API (albeit the docs aren't complete yet):
Here is the console app code that I have right now:
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://api.remot3.it/apv/v27/user/login");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.Headers.Add("developerkey", "***KEY***");
using (var streamWriter = new
StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = new JavaScriptSerializer().Serialize(new
{
email = "***EMAIL***",
password = "***PASSWORD***"
});
Console.WriteLine(json);
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Console.WriteLine(result);
Console.ReadLine();
}
}catch(Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
Console.ReadLine();
}
Expected output is some JSON data, but I am getting a NULL back from getResponse().
Try to serialize the credential in your form and for header send as parameter for this class.
Check below for my code. It is not 100 % fit to your requirement, but atleast it will help to get through your logic.
Here is what I get Json Response from this code. Its work Perfect. Please remember to add timeout option on your webrequest and at the end close the streamreader and stream after completing your task. please check this code.
public static string httpPost(string url, string json)
{
string content = "";
byte[] bs;
if (json != null && json != string.Empty)
{
bs = Encoding.UTF8.GetBytes(json);
}
else
{
bs = Encoding.UTF8.GetBytes(url);
}
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
req.Method = "POST";
if (json != string.Empty)
req.ContentType = "application/json";
else
req.ContentType = "application/x-www-form-urlencoded";
req.KeepAlive = false;
req.Timeout = 30000;
req.ReadWriteTimeout = 30000;
//req.UserAgent = "test.net";
req.Accept = "application/json";
req.ContentLength = bs.Length;
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(bs, 0, bs.Length);
reqStream.Flush();
reqStream.Close();
}
using (WebResponse wr = req.GetResponse())
{
Stream s = wr.GetResponseStream();
StreamReader reader = new StreamReader(s, Encoding.UTF8);
content = reader.ReadToEnd();
wr.Close();
s.Close();
reader.Close();
}
return content;
}

using OpenTSDB HTTP api in .NET : 400 Bad Request

I'm trying to use .net to put datapoints in OpenTSDB, using the HTTP /api/put API.
I've tried with httpclient, webRequest and HttpWebRequest. The outcome is always 400 - bad request: chunked request not supported.
I've tried my payload with an api tester (DHC) and works well.
I've tried to send a very small payload (even plain wrong, like "x") but the reply is always the same.
Here's one of my code instances:
public async static Task PutAsync(DataPoint dataPoint)
{
try
{
HttpWebRequest http = (HttpWebRequest)WebRequest.Create("http://127.0.0.1:4242/api/put");
http.SendChunked = false;
http.Method = "POST";
http.ContentType = "application/json";
Encoding encoder = Encoding.UTF8;
byte[] data = encoder.GetBytes( dataPoint.ToJson() + Environment.NewLine);
http.Method = "POST";
http.ContentType = "application/json; charset=utf-8";
http.ContentLength = data.Length;
using (Stream stream = http.GetRequestStream())
{
stream.Write(data, 0, data.Length);
stream.Close();
}
WebResponse response = http.GetResponse();
var streamOutput = response.GetResponseStream();
StreamReader sr = new StreamReader(streamOutput);
string content = sr.ReadToEnd();
Console.WriteLine(content);
}
catch (WebException exc)
{
StreamReader reader = new StreamReader(exc.Response.GetResponseStream());
var content = reader.ReadToEnd();
}
return ;
}
where I explicitly set to false the SendChunked property.
note that other requests, like:
public static async Task<bool> Connect(Uri uri)
{
HttpWebRequest http = (HttpWebRequest)WebRequest.Create("http://127.0.0.1:4242/api/version");
http.SendChunked = false;
http.Method = "GET";
// http.Headers.Clear();
//http.Headers.Add("Content-Type", "application/json");
http.ContentType = "application/json";
WebResponse response = http.GetResponse();
var stream = response.GetResponseStream();
StreamReader sr = new StreamReader(stream);
string content = sr.ReadToEnd();
Console.WriteLine(content);
return true;
}
work flawlessly.
I am sure I am doing something really wrong.
I'd like to to reimplement HTTP in Sockets from scratch.
I've found a solution I'd like to share here.
I've used wireshark to sniff my packets, and I've found that this header is added:
Expect: 100-continue\r\n
(see 8.2.3 of https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html)
This is the culprit. I've read the post http://haacked.com/archive/2004/05/15/http-web-request-expect-100-continue.aspx/ by Phil Haack, and found that HttpWebRequest puts that header by default, unless you tell it to stop. In this article I've found that using ServicePointManager I can do just this.
Putting the following code on top of my method, when declaring the http object, makes it work very well, and solves my issue:
var uri = new Uri("http://127.0.0.1:4242/api/put");
var spm = ServicePointManager.FindServicePoint(uri);
spm.Expect100Continue = false;
HttpWebRequest http = (HttpWebRequest)WebRequest.Create(uri);
http.SendChunked = false;

Categories

Resources