I'm using Azure Mobile Services from within a Xamarin.iOS app.
My service expects a custom header to be sent from the client.
In order to send this, I created my own message handler which I derive from `NativeMessageHandler (part of ModernHttpClient):
this.client = new MobileServiceClient (Constants.ApplicationURL, Constants.GatewayURL, new CustomMessageHandler ());
To get my header in there, the handler looks like this:
public class CustomMessageHandler: NativeMessageHandler
{
protected override Task<System.Net.Http.HttpResponseMessage> SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
request.Headers.Add ("customHeader", "headerValue");
return base.SendAsync (request, cancellationToken);
}
}
The problem is that the header doesn't seem to arrive at the server when my service is deployed to Azure. It works when running it locally in VisualStudio. If I put a breakpoint into my handler, it is hit; so the header really gets added.
Why would it work locally but not on Azure?
And the answer is: D'oh!
I enabled "Authentication" for my Azure App. Hence I would get a 401 for every request. It had nothing to do with my handler. Turned it off and it works like charm.
Related
I use Delgating handler to add correlation ids to inward requests to my application.
But, my MVC app makes frequent calls to remote domain https://remoteservice.net/xyz via an webapi client provided by them. The remote service API allows users to set correlation id via request header, but the webapi client doesn't provide a way to expose that.
So I am now thinking to set correlation id via owin pipeline for all outgoing remote calls from my MVC app. Is this possible? Any help?
You could extend an HttpClientHandler and add a correlationId header there:
public class CorrelatingHandler : HttpClientHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Headers.Add("currelationId", Guid.NewGuid());
return base.SendAsync(request, cancellationToken);
}
}
using(var client = new HttpClient(new CorrelatingHandler())){
.....
}
source: https://forums.asp.net/post/6025521.aspx
I have a 2 services(WebApi), one is azure cloud service that using IIS host and another one is azure service fabric stateless service that using Owin host. There is a handler that like below, and both services register this handler to handle the context(config.MessageHandlers.Add(new ContextHandler())).
Currently, what I met is: If I call cloud service api(just ping) using HTTP HEAD request, this will return '405 method not allowed'. But if I call fabric service, I will get 'Could not get any response' with 'there was an error connecting to...'.
When debug the code. For the cloud service using IIS, in the below code, the response.Content has no value. But for the fabric service using Owin, the response.Content has value '405 Method not allowed'.
My question is, what the difference between them? Why the Owin will return a response with content back as the request is HEAD request?
Thanks.
public class ContextHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
// initialize context
using (new ApiRequestContextWrapper(request))
{
var context = ApiRequestContext.Current;
context.Log.Trace(
$"API Call {request.Method.Method}
{request.RequestUri.GetLeftPart(UriPartial.Path)}");
var response = await base.SendAsync(request,
cancellationToken).ConfigureAwait(false);
return response;
}
}
}
I've been reading about custom auth methods using Azure, and stumbled upon 12 Days of ZUMO. It's an excellent write up, but I can't seem to find anything related to IServiceFilter in the current .Net Client SDK for Azure.
I'm developing a Xamarin app in C#.
Has this functionality been removed or relocated? I have all Azure namespaces referenced and intellisense can't find IServiceFilter or anything else related to service filters.
Thanks for reading.
I currently develop an app for Android on Java (I don't think that library for C# is very different).
And I can access ServiceFilter. But I don't see IServiceFilter.
Namespace - com.microsoft.windowsazure.mobileservices.http.ServiceFilter
Library version - 2.0.2-beta2
In Xamarin you need to use a DelegateHandler instead. This is the standard .net way to filter http traffic.
public class MyLogFilter : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
// Do any pre-request requirements here
Log.Warning("http request", request.RequestUri.ToString() );
// Request happens here
var response = await base.SendAsync(request, cancellationToken);
// Do any post-request requirements here
Log.Warning("http response", response.StatusCode + " " + response.Content.ReadAsStringAsync().Result);
return response;
}
}
Once you've done that, you just chain the handler when initializing your MobileServiceClient, changing this:
Client = new MobileServiceClient (API_URL, new MyExistingHandler());
to:
Client = new MobileServiceClient (API_URL, new MyLogFilter(), new MyExistingHandler());
I am having a tough time figuring this out, but when I use a custom message handler in my Web API (created in VS2013) none of the /token request get processed through my handler.
What I'm trying to do is assist our support crew by implementing some logging to save request / response values for a few days. This will allow them to see the request and responses as raw as possible.
It's working, for everything except "/token" requests. We need to process the requests and responses for "/token" and "/authenticate" as a large percentage of our support calls end up being username and password issues.
I also need to do this in a message handler so I can isolate the code to message handlers.
Here is a sample handler I'm testing with in an isolated project. It's only in place ATM to debug/test this issue. I've also implemented a DelegatingHandler as well with the same results.
public class MyMessageProcessingHandler : MessageProcessingHandler {
protected override HttpRequestMessage ProcessRequest(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) {
Trace.WriteLine(string.Format("{0} {1}", request.Method, request.RequestUri));
return request;
}
protected override HttpResponseMessage ProcessResponse(HttpResponseMessage response, System.Threading.CancellationToken cancellationToken) {
Trace.WriteLine("response!");
return response;
}
}
in WebApiConfig.Register method I add the message handler to the config's message handler collection.
(I also tried Global.asax.cs is the Application_Start method)
GlobalConfiguration.Configuration.MessageHandlers.Add(new MyMessageProcessingHandler());
The order doesn't seem to matter - I've tried it as the first line of code, or the last.I've tried to Insert after the passive message handler is added by
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
GlobalConfiguration.Configuration.MessageHandlers.Insert(0, new MyMessageProcessingHandler());
Whenever I make an api/Values request or any api/Controller request the custom message handler handles the request just fine. However, when I post (or get) to /token (yes-properly) the custom message handler doesn't process the request.
I would like to know how to use a Message Handler to process the /token & /authenticate requests. I appreciate all your help!
Thanks,
-Rick
I went with a custom IHttpModule. It ended doing what I wanted in the way I wanted it by giving me direct access to the requests and allowing me to inspect them; even the authentication requests.
Thanks to all that looked at my issue.
We are using a self hosted WebApi and we are required to remove the server header (Server: Microsoft-HTTPAPI/2.0) of the responses sent.
Since it is self hosted, a HttpModule is not an option. Implementing a DelegatingHandler, access to headers as well as adding is possible. The asp.net website nicely details how one can do that.
But the server header seems to be added much later in the pipeline since it is not set in the HttpResponseMessage we return from the DelegatingHandler. However, we are able to add values.
async protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
response.Headers.Server.Add(new ProductInfoHeaderValue("TestProduct", "1.0"));
response.Headers.Add("Server", "TestServerHeader");
return response;
}
Both Server.Add and .Add work as expected. response.Headers.Remove("Server"); however does not work, because the server header is not set, response.Headers.Server is empty.
Is there anything i am missing?
There is no code solution to remove Server HTTP header on self host.
The only solution is to edit windows registry:
https://learn.microsoft.com/ru-ru/archive/blogs/dsnotes/wswcf-remove-server-header
add
appBuilder.Use((context, next) =>
{
context.Response.Headers.Remove("Server");
context.Response.Headers.Add("Server", new[] { "" });
return next.Invoke();
});
to Startup Configuration method just before
config.EnsureInitialized();