ServiceStack: How to transfer the original HttpRequest (ASP.NET) - asp.net

I am using a third-party handset detection library which receives the HttpRequest object as a parameter. My problem is that I need to have the code for using this library in a web-service.
I wanted to use ServiceStack since it's supposed to be much faster than other technologies.
But by using ServiceStack I haven't found any way of sending the HttpRequest from my website to the service. I have found a way to set the UserAgent like this:
var client = new JsonServiceClient(BaseUrl);
client.LocalHttpWebRequestFilter = request => request.UserAgent = Request.UserAgent;
but nothing more than that.
Is there any way to achieve this?

Related

Xamarin Forms application - Force IPv4 to HttpClient

It appears that this can be achieved by setting up a callback function to the ServicePoint.
The solution (although the goal is different, the same technique can be used) is discussed in this question Specify the local endpoint for HTTP request.
Following it, I tried
var servicePoint = ServicePointManager.FindServicePoint(new Uri(uri));
servicePoint.BindIPEndPointDelegate = (servicePoint, remoteEndPoint, retryCount) =>
{
if (remoteEndPoint.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
return new IPEndPoint(IPAddress.Any, 0);
}
throw new InvalidOperationException("no IPv4 address");
};
var _client = new HttpClient();
HttpResponseMessage response = await _client.GetAsync(uri);
expecting that the callback is called at the GetAsync() but it is not.
It would be much appreciated if someone tells me what I am missing.
Or, a completely different approach to achieve my goal, to force IPv4 at connections that HttpClient makes, would also be very much welcome.
Thanks in advance for your help.
Update
In the question How to use HttpClient to send a Request from a specific IP address? C#, someone says "... the .net core team have implemented the HttpClientHandler etc without bothering to put anything related to service points in there ..."
To confirm, I build the above code both with Framework4.7 and Core3.1 to find out that indeed, when built with Core, the callback is NOT called.
A Xamarin project targets .Net standard, which is a Core if I am not mistaken. I guess I need to forget this ServicePoint stuff and look for other solutions...
Again, your insight will be very much appreciated!

Get the raw request that is sent with HttpClient and HttpRequestMessage

In my C# code running .NET 6 (Azure Function) I am sending an HttpRequestMessage using HttpClient. It doesn't work but it should work, so I want to get the raw request that I am sending, including the header, so I can compare with the documentation and see the differences.
In the past I have used Fiddler but it doesn't work for me now, probably because of some security settings on my laptop. So I am looking for a solution within the world of Visual Studio 2022 or .NET 6 where I can get the raw request out for troubleshooting purposes.
This question is not really about code, but here is my code anyway.
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://myendpoint.com/rest/something");
var apiToken = "AOU9FrasdgasdfagtHJNV";
request.Headers.Add("Authorization", "Basic " + apiToken);
var message = new
{
sender = "Hey",
message = "Hello world",
recipients = new[] { new { id = 12345678} }
};
request.Content = new StringContent(JsonSerializer.Serialize(message), Encoding.UTF8, "application/json");
request.Headers.Add("Accept", "application/json, text/javascript");
HttpResponseMessage response = await httpClient.SendAsync(request);
When SendAsync is invoked, I wish to know what exactly is sent, both header and content.
If you cannot use any proxy solution (like Fiddler) then I can see 2 options. One is described in comments in your question to use DelegatingHandler. You can read more about this in documentation. What is interesting is that HttpClient supports logging out of the box which is described in this section https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-6.0#logging of the article which describes DelegatingHandlers
If you are worried that something will manipulate the outgoing request then you can implement option 2. This is to create temporary asp.net core application with .UseHttpLogging() middleware plugged in into pipeline as described here https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-logging/?view=aspnetcore-6.0 That way you will know exactly how your request looks like from application which is being requested point of view. Now if you will point your azure function to you temporary app - you should see what gets send
Hope it helps

Making Request to API Gateway with ASP.NET SDK

I am trying to make a reques to API Gateway with the AWS SDK for .NET but I have no idea how to do that. The documentation is very lacking and there are no examples posted online of it.
This is as far as I've gotten so far:
const String awsAccessKeyId = "43789hf872hy832h"; // Get access key from a secure store
const String awsSecretAccessKey = "4738fbdhskjfy932hjk"; // Get secret key from a secure store
var client = new AmazonAPIGatewayClient(awsAccessKeyId, awsSecretAccessKey,RegionEndpoint.USEast1);
But I don't know how to make a get request to one of my APIs.
Does anyone have any experience dealing with this?
The AmazonApiGatewayClient isn't meant for invoking your API's, but rather a client for managing your ApiGateway resources. If you would like to invoke your endpoints, you should be using an HTTP client for this.
Here is one you can use from within C#, but you can also use your browser, or a tool like Postman or Fiddler.

How to post form data with ASP.NET MVC 6 from backend to another url?

I have some data in my app's backend that I need to post from my application to another application.
I was thinking about creating form, filling it with the data and auto-posting with javascript within onLoad. But this seems somehow outdated practice for me. What would be the correct way to post from backend to some other application's url using ASP.NET 5 & MVC6 features?
Note: preferably, it should be JSON & RESTful design (controller will be accepting the data on another end), though I don't think this should change anything.
You should be able to use e.g. ordinary HttpClient. This is an example from the MS blog.
using System.Net.Http;
using (var client = new HttpClient())
{
var baseUri = "http://playapi.azurewebsites.net/api/products";
client.BaseAddress = new Uri(baseUri);
client.DefaultRequestHeaders.Accept.Clear();
var response = await client.GetAsync(baseUri);
if (response.IsSuccessStatusCode)
{
var responseJson = await response.Content.ReadAsStringAsync();
//do something with the response here. Typically use JSON.net to deserialise it and work with it
}
}
This is a GET example, but POST should be pretty similar. If you control both servers, then you can use a fancy thing called Swagger (and Swashbuckle nuget package for .NET). It is kind of WSDL for the REST API, it can generate full proxy to access your API, similar to what WCF does + a nice page with documentation and testing forms.
P.S. Not sure of the state of Swashbuckle for ASP.NET Core, but the pre-release version is available on Nuget as well.

SignalR wth gzip compression

Having some problem developing a SignalR client for a Hub hosted in asp.net website with gzip compression enabled. Since we are using IIS compression, the response from SignalR also gets compressed, but, the client does not understand the response and we get a Json parsing error on the client side.
SignalR internally uses HttpWebRequest to make make http requests and HttpWebRequest can be configured to automatically decompress the response using AutomaticDecompression property. So, if somehow I can get hold of the HttpWebRequest object used by SignalR to make the request, I should be able to set the enable automatic decompression.
I thought I should be able to get access to the HttpWebRequest by providing HubConnection.Start with my custom implementation of IHttpClient, IHttpClient.GetAsync takes a prepareRequest action which I thought should give me access to the HttpWebRequest, but, HttpHelper.GetAsync wraps the HttpWebRequest with HttpWebRequestWrapper before passing to prepareRequest and HttpWebRequestWrapper does not provide access to HttpWebRequest.
HttpHelper class is internal so can't use it as well, so, I am not exactly sure how to enable automatic decompression with SignalR.
I can expose the HttpWebRequest in HttpWebRequestWrapper, but, would prefer a simpler solution if one exists. Any thougths?
I am using SignalR version 0.5.1.10822
My auto decompression HttpClient:
public class HttpClientWithAutoDecompression : IHttpClient
{
readonly DefaultHttpClient _httpClient = new DefaultHttpClient();
private readonly DecompressionMethods _decompressionMethods;
public HttpClientWithAutoDecompression(DecompressionMethods decompressionMethods)
{
_decompressionMethods = decompressionMethods;
}
public Task<IResponse> GetAsync(string url, Action<IRequest> prepareRequest)
{
Task<IResponse> task = _httpClient.GetAsync(url,
request =>
{
[ERROR: request is actually HttpRequestWrapper and
does not expose HttpWebRequest]** ]
var httpWebRequest = (HttpWebRequest) request;
httpWebRequest.AutomaticDecompression = _decompressionMethods;
prepareRequest(request);
});
return task.ContinueWith(response =>
{
Log.Debug(this, "Response: {0}", response.Result.ReadAsString());
return response.Result;
});
}
....
}
To the best of my knowledge GZip encoding and streaming do not mix. In the case of the forever frame transport the client wouldn't be able to decode any on the streaming content until the entire response, or at least a significant block of data, is received (due to the way the data is decoded). In the case of web sockets there is not support for encoding of any kind at this time, although there is apparently an extension to the specification for per message encoding being worked on.
That said, if you wanted to attempt to provide support for the LongPolling transport, the only way I can see this being possible is to provide your own SignalR IHttpClient implementation. You can see right now that the DefaultHttpClient class uses HttpHelper::GetAsync which creates the HttpWebRequest internally and you can never get your hands on that because you only have access to the IRequest which is HttpWebRequestWrapper at that point.
By creating your own IHttpClient you can take over the initial instantiation of the HttpWebRequest, set the AutomaticDecompression and then wrap that up yourself with the HttpWebRequestWrapper.

Resources