Getting an XML sent by Webservice(POST method) in C# .NET - c#

I am developing this application where I need to send an XML file to a webservice and read it from the webservice, and applying the business logic from the webservice, it will send an XML as response.
The thing is that I do know how to read the response the webservice sends, but I don't know how to retrieve the XML that the request sends to the webservice, the variable always comes null. If someone could help me out, I'd be really glad.
Request Method:
(...)
using (var client = new HttpClient())
{
var XMLRequest = Util.BuildXML.CreateRequestXML();
string url = string.Format(WEB_API_HOST + "/Application/MyMethod/");
HttpRequestMessage httpRequest = new HttpRequestMessage()
{
RequestUri = new Uri(url, UriKind.Absolute),
Method = HttpMethod.Post,
Content = new StringContent(XMLRequest.ToString(), Encoding.UTF8, "text/xml")
};
var task = client.SendAsync(httpRequest).ContinueWith((taskwithmsg) =>
{
var response = taskwithmsg.Result;
if (response.IsSuccessStatusCode)
{
var xmlResponse = response.Content.ReadAsStringAsync().Result;
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlResponse);
var test = doc.SelectSingleNode("RESPONSE/...").InnerText;
}
else
{
var contentTask = response.Content.ReadAsStringAsync().Result;
throw new Exception(contentTask);
}
});
task.Wait();
}
(...)
And the Webservice ( that is supposed to receive the XML and read it)
[AcceptVerbs("GET", "POST")]
public HttpResponseMessage MyMethod(XmlDocument doc)
{
// Any doc.SelectSingleNode() wouldn't work, the doc variable is null.
var response = new StringBuilder();
response.Append("<?xml version=\"1.0\" standalone=\"yes\"?>");
response.Append("<RESPONSE>");
(...)
response.Append("</RESPONSE>");
var xmlResponse = new HttpResponseMessage()
{
Content = new StringContent(response.ToString(), Encoding.UTF8, "text/xml")
};
return xmlResponse;
}
So how do I get to read the xml in the "MyMethod" method?
Thanks a bunch!

Related

How to redirect call to API from particular proxy server?

I have an API which i want to get access from one of my proxy server only. As that server have given all access to access that particular API. So I have single endpoint.
I have proxy server URL and Port and i want to add proxy settings in my app settings file and implement it so when call is given to API, that particular call pass through the Proxy server.
Please assist me how can I achieve this?
Current Call to API as below.
PushMessageAndroidRequest req = new PushMessageAndroidRequest();
req.registration_ids = list.Select(x => x.Token).ToList();
req.data = new AndroidData() { Payload = CommonLib.ConvertObjectToJson(payload) };
response = await RequestHandler.PostDataAsync<PushMessageResponse>(_appConfig.pushMessageConfigs.Url, req, new List<KeyValue>() { new KeyValue("Authorization", "key=" + _appConfig.pushMessageConfigs.Key) });
Sample code have written
public static async Task<ResJsonOutput> ProxyDataAsync(string ApiPath,string obj, List<KeyValue> Headers = null)
{
ResJsonOutput result = new ResJsonOutput();
HttpResponseMessage response = new HttpResponseMessage();
var requestUri = string.Format(ApiPath);
var request = (HttpWebRequest)WebRequest.Create(requestUri);
WebProxy myproxy = new WebProxy(Settings.ProxyAddress, Settings.ProxyPort);
myproxy.BypassProxyOnLocal = false;
request.Proxy = myproxy;
using (WebResponse response = request.GetResponse())
{
using (StreamReader stream = new StreamReader(response.GetResponseStream()))
{
//JObject jResponse = JObject.Parse(stream.ReadToEnd());
//var isSuccess = jResponse.Value<bool>("success");
//result = (isSuccess) ? true : false;
}
}
return result;
}

How to post file and data to api using httpclient

I am at learning phase and i want to post file and data to api using httpclient.
i have tried this.
Here is my controller code
string baseUrl = ServerConfig.server_path + "/api/Payment/AddMedicineOrder";
Dictionary parameters = new Dictionary();
parameters.Add("username",user.Username);
parameters.Add("FullName", FullName);
parameters.Add("Phone", Phone);
parameters.Add("CNIC", CNIC);
parameters.Add("address", address);
parameters.Add("Email", Email);
parameters.Add("dateofbirth", dateofbirth.ToShortDateString());
parameters.Add("Gender", Gender);
parameters.Add("PaymentMethod", PaymentMethod);
parameters.Add("Title", Title);
parameters.Add("PhramaList", medList);
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://localhost:44391/");
MultipartFormDataContent form = new MultipartFormDataContent();
HttpContent content = new StringContent("fileToUpload");
HttpContent DictionaryItems = new FormUrlEncodedContent(parameters);
form.Add(content, "fileToUpload");
form.Add(DictionaryItems, "medicineOrder");
var stream = PostedPrescription.InputStream;
content = new StreamContent(stream);
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "fileToUpload",
FileName = PostedPrescription.FileName
};
form.Add(content);
var response =await client.PostAsync("/api/Payment/AddMedicineOrder", form);
var k =response.Content.ReadAsStringAsync().Result;
How to pass this in Web api Method
[HttpPost]
public async Task<API> AddMedicineOrder()//string key, [FromUri]MedicineOrder medicineOrder
{
var request = HttpContext.Current.Request;
bool SubmittedFile = (request.Files.Count != 0);
this.Request.Headers.TryGetValues("medicineOrder", out IEnumerable<string> somestring);
var k = somestring;
return OK("Success");
}
catch (Exception ex)
{
return InternalServerError("Technical Error.");
}
please help me. Thanks in advance
You need to support add multipart/form-data support to your web api. For this you can add custom media type formatter which will read your json content, as well as file content and you can bind that to a concrete model directly.

Post call for xml content using HttpClient

How to make xml content compatible with HttpClient's PostAsync operation for the content and where do you specify the headers for Content-Type = application/xml.
Error -> Cannot convert string to HttpContent
public async Task GetCustomersAsync(string firstname, string lastname)
{
using (var client = new HttpClient())
{
var content = "<soapenv:Envelope xmlns:xsi...";
var response = await client.PostAsync("https://domain.com/scripts/WebObj.exe/Client.woa/2/ws/ABC", content);
var responseString = await response.Content.ReadAsStringAsync();
}
}
My guess is what you want to do is the following:
public async Task<string> GetCustomersAsync(string firstname, string lastname)
{
using (var client = new HttpClient())
{
var content = new StringContent("<soapenv:Envelope xmlns:xsi...", Encoding.UTF8, "application/xml");;
var response = await client.PostAsync("https://example.com/scripts/WebObj.exe/Client.woa/2/ws/ABC", content);
return await response.Content.ReadAsStringAsync();
}
}
OR
using (var request = new HttpRequestMessage { RequesteUri = new Uri("POST_URL"), Method = HttpMethod.Post })
{
var content = new StringContent("<soapenv:Envelope xmlns:xsi...");
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
}
You can refer here to more information about other Content types that can be created and passed.
To specifically request xml content in response you must define the content type in the header of the content. The MediaTypeHeaderValue is parsed and set in the ContentType property of the content Headers. Here is a complete example of the code;
using (var client = new HttpClient())
{
var content = new StringContent(messageToPOST, Encoding.UTF8, "text/xml");
content.Headers.ContentType = MediaTypeHeaderValue.Parse("text/xml");
response = await client.PostAsync(_uri, content);
responseMsg = await response.Content.ReadAsStringAsync();
}
The responseMsg property returned by the request as the response can be parsed as a string and otherwise converted to and validated as xml using an expression such as
XDocument xdoc = XDocument.Parse(responseMsg);
string xmlAsString = xdoc.ToString();

How do I extract an uri out of a XML response from an API

I am currently creating an API which accepts the string like "sample input" as input parameter. This API should be calling other third party API passing the same value we got as the input like
https://thirdpartyhost/api/dept?name=sample+input
which returns an xml like
<lab:labs>
<lab uri="https://thirdpartyhost/api/dept/1">
<name>sample input</name></lab>
</lab:labs>
I will need to retrieve the uri from the <lab uri="https://thirdpartyhost/api/dept/1"> which will give us the required response.
public IHttpActionResult Get(string DeptName)
{
using (var client = new HttpClient())
{
string BaseURL = ConfigurationManager.AppSettings["BaseURL"];
Uri uri = new Uri(BaseURL);
client.BaseAddress = uri;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
var response = client.GetAsync("api/v2/dept?name=" +LabName).Result;
if (response.IsSuccessStatusCode)
{
string responseString = response.Content.ReadAsStringAsync().Result;
}
}
I am not sure how to extract the uri from the response from the API. Any help is greatly appreciated with this
Using AngleSharp, you can do as follows:
var xmlString = "<lab:labs><lab uri=\"https://thirdpartyhost/api/dept/1\"><name> sample input </name></lab></lab:labs>"
var parser = new HtmlParser();
var parsedXml = parser.Parse(xmlString);
var extractedUri = parsedXml.QuerySelectorAll("lab").Attr("uri").FirstOrDefault();
Try this:
string xmlString = #"<lab:labs>
<lab uri=""https://thirdpartyhost//api//dept//1"">
<name>sample input</name></lab>
</lab:labs>".Replace("lab:labs>", "labs>");
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlString);
XmlNodeList nodes = doc.SelectNodes("labs//lab");
if (nodes != null && nodes.Count > 0)
{
XmlNode node = nodes[0];
if (node.Attributes["uri"] != null)
{
string uri = node.Attributes["uri"].Value.ToString();
}
}
The replace will remove the namespace you are not using and xmlString is your responseString.

mailgun email validation response

I am a newbie to Mailgun and REST and need some help.
If I use the Mailgun provided code:
RestClient client = new RestClient();
client.BaseUrl = "https://api.mailgun.net/v2";
client.Authenticator = new HttpBasicAuthenticator("api", "xxxx");
RestRequest request = new RestRequest();
request.Resource = "/address/validate";
request.AddParameter("address", "me#mydomain.com");
return client.Execute(request);
How do I retrieve and process the response that the address is valid or not?
This code works for me. I didn't use RESTClient and wrote my own code(which works perfectly fine)
[System.Web.Services.WebMethod]
public static object GetEmailInfo(string UserName)
{
var http = (HttpWebRequest)WebRequest.Create("https://api.mailgun.net/v2/address/validate?address=" + UserName);
http.Credentials = new NetworkCredential("api","public key");
http.Timeout = 5000;
try
{
var response = http.GetResponse();
var stream = response.GetResponseStream();
var sr = new StreamReader(stream);
var content = sr.ReadToEnd();
JSON.JsonObject js = new JSON.JsonObject(content);
return Convert.ToBoolean(js["is_valid"]);
}
catch (Exception ex)
{
}
}
First of You should never post private information such as your public key of such API
Just by using the amazing Postman Chrome app you can see the result of such request:
click here to see the image below in full resolution
and I'm sure, if you instead of return client.Execute(request); you do
var result = client.Execute(request);
return result;
and adding a breakpoint in the return you can inspect what is the object that is passed from the call... without testing, I'm sure you can convert result.Content (as it's where RestSharp appends the response content) into an object and use that object (or use the dynamic type).
now, testing your code in VS:
click here to see the image below in full resolution
you can then use the dynamic object like:
click here to see the image below in full resolution
public void GetResponse()
{
var client = new RestClient();
client.BaseUrl = "https://api.mailgun.net/v2";
client.Authenticator = new HttpBasicAuthenticator("api", "pubkey-e82c8201c292691ad889ace3434df6cb");
var request = new RestRequest();
request.Resource = "/address/validate";
request.AddParameter("address", "me#mydomain.com");
var response = client.Execute(request);
dynamic content = Json.Decode(response.Content);
bool isValid = content.is_valid;
string domain = content.parts.domain;
}
and treat the content of the response just like the json passed:
{
"address": "me#mydomain.com",
"did_you_mean": null,
"is_valid": true,
"parts": {
"display_name": null,
"domain": "mydomain.com",
"local_part": "me"
}
}

Categories