Posting XML as request body to Java Rest in c# - c#

I have application built with C# that consume Restful built with Java Expecting XML as request body.How do i go about it ?

Need more more information on what you are doing specifically what c# http stack you are using. It should not matter what the technology the service is written.
Here is one way you could accomplish this
1) Install HttpClient from Nuget. It's version 0.5.0.0
2) Use the following code
var client = new System.Net.Http.HttpClient();
var url = #"http://localhost:9999/books";
var content = new StringContent("<book><title>some title</title></book>", Encoding.UTF8, "application/xml");
client.Post(url, content);
HttpClient is very easy to use and can be discussed here http://wcf.codeplex.com

Related

Calling Azure Function app works in console but not in xamarin forms

So I created a function which is a Get request. All the function does is retrieves some data from an SQL database and returns it.
I call this function in a console app, just to test it, and all is working as it should.
I then copy the code and paste it into my xamarin.forms app for android.
When I run it it immediately gives me a 404 Not found response.
Any idea why it's not working in the xamarin app but is working in the console app?
using (var client = new HttpClient())
using (var request = new HttpRequestMessage(HttpMethod.Get, "http://{MySite}.azurewebsites.net/api/{myfunction}/"))
using (var httpContent = CreateHttpContent(new DiaryDate() { Date = DateTime.Today }))
{
request.Content = httpContent;
using (var response = await client
.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken)
.ConfigureAwait(false))
{
if (response.IsSuccessStatusCode)
{
// do something
}
}
}
CreateHttpContent just converts the given object to JSON.
Update the URL to https scheme (https://{MySite}.azurewebsites.net/api/{myfunction}/). Firstly, there is no reason for choosing non-secure channel. Azure Function side won't require any change to use https. Secondly, as pointed out in the other answer, there is restriction in client side for http which would require tweak to unblock.
UPDATE: In this particular call, you are using Http GET, but sending a request content (json of DiaryDate object). So, it will send that via query string in the the URL. Though I am not yet sure how it's working in console app (might be something to do with how it's handled in Xamarin/Mono http handler v/s that of .net core in console app in GET request), but it should be POST surely. Can you change HttpMethod.Get to HttpMethod.Post in the line where you are creating HttpRequestMessage.

Forwarding the entire received request "as is" using HttpClient

I have a thin frontend API web service that does some preprocessing on the received data and then sends the data to my backend API web service using HttpClient.
There are some complex cases when a request contains multipart data with JSON and files, and I don't want to parse it at all in the frontend. The backend will do the job.
So, I would like to take the request "as is" - as raw as possible (not caring about its contents and whether it's multipart or not) and just forward it to the backend API.
I tried the following:
var msg = new HttpRequestMessage(HttpMethod.Post, resourceUrl);
msg.Content = new StreamContent(request.Body);
var apiResponse = await _httpClient.SendAsync(msg);
but the backend web service receives an empty request body with 0 length.
How do I forward the entire request body without having to analyze it and reassemble a new request body?
You need to set msg.Content.ContentLength for this to work correctly. It's also a good idea to copy ContentType and other content headers from the request into msg.Content, so that your backend service knows how to parse it.

System.Net.Http.HttpClient cannot connect to web API via NSwag client (Windows Universal Platform)

I wrote a simple .Net Core 3.0 API using Swashbuckle Swagger and generated an api client via NSwag Studio, then I put a generated Api Client to a .Net Standard 2.0 project.
I have a Universal Windows Platform application, which is meant to be connecting to the Web Api and send/receive data etc.
I put a simple code in MainPage.xaml.cs class with System.Net.Http.HttpClient inside
public MainPage()
{
this.InitializeComponent();
var httpClient = new HttpClient();
var apiClient = new ApiClient(ProjectConstants.API_URL, httpClient);
var deviceService = new DeviceService(apiClient);
}
When API is called later in deviceService my program throws an exception on SendAsync method in generated Api Client
"An error occurred while sending the request."
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
I tested API Client and HttpClient on .Net Core console app and it worked fine.
I read about Http Client for UWP https://learn.microsoft.com/en-us/windows/uwp/networking/httpclient but it seems UWP should support System.Net.Http.HttpClient too, which I would love to stick to.
Is this a Universal Windows Platform bug or do I forgot about adding something necessary to a project?
The System.Net.Http.HttpClient API can be used across platforms, but we do recommend using APIs from Windows.Web.Http.HttpClient NameSpace which is easy to use. So you could use Windows.Web.Http.HttpClient API in UWP,and use GetAsync(PostAsync) to send a request, for example:
Uri requestUri = new Uri("http://www.contoso.com");
Windows.Web.Http.HttpClient httpClient = new Windows.Web.Http.HttpClient();
Windows.Web.Http.HttpResponseMessage httpResponse = new Windows.Web.Http.HttpResponseMessage();
httpResponse = await httpClient.GetAsync(requestUri);
For more information about the differences between Windows.Web.Http and System.Net.Http.HttpClient, you can refer to this article
Does it have the same api as the portable HttpClient?

How to use RestRequest/RestResponse when the web service produces multipart form data in C#?

I have a web service in a RESTful web server (java) which consumes media of type APPLICATION_FORM_URLENCODED and produces media of type MULTIPART_FORM_DATA. Now I'm working on a REST client (C#) and trying to use this web service. I'm using RestSharp as the REST client. My code goes as follows:
RestRequest request = new RestRequest("getDataFileChunkIS", Method.POST);
request.AddParameter("sessionId", sessionId);
request.AddParameter("dataFileId", dataFileId);
request.AddParameter("offset", offset);
request.AddParameter("chunkSize", chunkSize);
request.AddParameter("checksumFlag", checksumFlag);
RestClient client = new RestClient(url);
RestResponse response = (RestResponse)client.Execute(request);
But in this response I'm getting HTTP Status 406 - Not Acceptable. It says "The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers." Maybe I'm doing it in a wrong way. So my question is that how can I execute this request whose response will contain MULTIPART_FORM_DATA ?
1) how can I execute this request whose response will contain MULTIPART_FORM_DATA?
request.AddHeader("Accept", "multipart/form-data")
2) how can I read this response header(contains JSON) using RestClient?
See answers to this question. Particularly the third one, which shows how to do it just with .NET 4.5 libraries.
You may need to implement IDeserializer to get access to the raw HttpResponse for consumption.

Server Name Indication from C#

As far as I can tell, there seems to be a big limitation in .NET in that there is no way using C# and .NET to make an TLS connection that uses Server Name Indication (SNI). Have I missed something or is my understanding correct?
Does anybody know if and how I could make an SNI connection using OpenSSL.NET, libcurl.NET or some other 3rd party .NET library? Some sample code would be very much appreciated.
In my .Net 4.5 project the following fails for a server using SNI:
var url = "https://www.somesite.com";
System.Net.WebClient client = new System.Net.WebClient();
client.Encoding = Encoding.UTF8;
var data = client.DownloadString(url);
But it works if explicitly specifying TLS1.2 by prefixing it with:
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
The same applies to webrequest:
WebRequest request = WebRequest.Create("https://www.somesite.com");
and HttpRequestMessage:
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "https://www.google.com");
They all need the protocol explicitly set to TLS 1.2 to work with an SNI server (this may have changed in newer .Net versions)
This is a fairly old post but still this answer might help some people, at least it cost me some days.
.NET Framework does support the Server Name Indication by default. (Tested on 4.5.1 but I guess it's same at least for .NET 4.5+)
A short example:
HttpResponseMessage response;
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "https://www.google.com");
var handler = new HttpClientHandler
{
CookieContainer = new CookieContainer()
};
using (var client = new HttpClient(handler))
{
response = client.SendAsync(httpRequestMessage).Result;
}
This is a very standard way to create a GET request within C#. You will see, this example does run using, in my case, TLS 1.2 with SNI. If you use Wireshark to see the actual packages which are sent, you will see a Client Hello with the Server Name Indication set to www.google.com.
An issue we ran into: The SNI tag is set by the .NET Framework (or Schannel by Windows, not sure) based on the URL passed in the constructor of HttpRequestMessage. If you know initialize the request based on some URL (for example https://www.google.com) and later on you switch the RequestUri OR the Host header, the SNI tag will still be created based on the original url URL. This might be the case for example if you pass through a request and you remap all original headers to the newly created request.

Categories