How do I register a custom IHttpModule with HttpServer - asp.net-web-api

I am using the HttpServer class to test my web api. In my application, I have a custom IHttpModule that handles some URL rewriting. I need this module to process the requests for my web api as well. Here is my code that I use to create the HttpServer object.
var config = new HttpSelfHostConfiguration(ServerUrl);
RouteConfig.RegisterRoutes(config.Routes);
FilterConfig.RegisterWebApiFilters(config.Filters);
var httpServer = new HttpServer(config);
Can someone tell me the obvious thing I am missing that I need to do to register my module with the server?

AFAIK you can't use HttpModules with a self hosted WebAPI server. I think what you need is a MessageHandler.
Http Message Handlers
DelegatingHandler (MSDN)

Related

NServiceBus and ApiController

i try to configure my NServiceBus for a WebApi. I've tried this one: https://coderkarl.wordpress.com/2012/03/16/injecting-nservicebus-into-asp-net-webapi/
The Problem is the Syntax has been changed in the newest NServiceBus-Versin. I can't use the Functions for the Configure-Class because they will be removed in further Versions. The new way to configure the Bus is using the BusConfiguration-Class but i have no idea how.
Here is the older Code:
public static Configure ForWebApi(this Configure configure)
{
// Register our http controller activator with NSB
configure.Configurer.RegisterSingleton(typeof(IHttpControllerActivator),
new NSBHttpControllerActivator());
// Find every http controller class so that we can register it
var controllers = Configure.TypesToScan
.Where(t => typeof(IHttpController).IsAssignableFrom(t));
// Register each http controller class with the NServiceBus container
foreach (Type type in controllers)
configure.Configurer.ConfigureComponent(type, ComponentCallModelEnum.Singlecall);
// Set the WebApi dependency resolver to use our resolver
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NServiceBusResolverAdapter(configure.Builder));
// Required by the fluent configuration semantics
return configure;
}
And Application_Start():
AreaRegistration.RegisterAllAreas();
// Use LocalDB for Entity Framework by default
Database.DefaultConnectionFactory = new SqlConnectionFactory("Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True");
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
BundleTable.Bundles.RegisterTemplateBundles();
Configure.WithWeb()
.DefaultBuilder()
.ForWebApi() // <------ here is the line that registers it
.Log4Net()
.XmlSerializer()
.MsmqTransport()
.IsTransactional(false)
.PurgeOnStartup(false)
.UnicastBus()
.ImpersonateSender(false)
.CreateBus()
.Start();
Does someone has managed it for the NServiceBus Version 5?
As wlabaj says, the documentation on the particular website says it all. Almost.
We use AutoFac so we don't need any direct reference to IBus or ISendOnlyBus and therefor we do this
ContainerBuilder builder = new ContainerBuilder();
var container = builder.Build();
configuration.UseContainer<AutofacBuilder>(x => x.ExistingLifetimeScope(container));
What we do in WebAPI and ASP.NET applications is this
NServiceBus.Bus.CreateSendOnly(configuration);
Because it's not a good practice to expect reply messages to come back after sending them.
Here you can see 3.0 vs 4.0 vs 5.0 configuration syntax. At the top of the page you have a link to download code samples.
The examples are for ASP .NET though, so you'll need to tweak it slightly for WebAPI. Let me know if you need further help with that.
ForWebApi was never a part of NServiceBus, this was an extension method from the sample that was used to configure NServiceBus dependency resolver to instantiate controllers. The way how it was done is shown here.
There is no need to use NServiceBus resolver since it is just a wrapper around another container. By default it uses Autofac, so you can just use Autofac to work for you in the whole application.
Autofac WebAPI integration is properly described in the documentation.
NServiceBus documentation has a page about using your own container.
This is a very well known setup that you can easily implement.

how web Web API in-memory hosting load our controllers classes?

I just learn about Web API in-memory hosting right now, It's new stuff for me. I download the Web API self hosting nuget package and just configure the Routing for Web API and reference the Web API project to In Memory hosting project. And everything is working, but I don't know how in-memory can recognize any controller classes in my Web API project. Is there anyone who can explain me about this?
private HttpServer _server;
private string _url = "http://api.mydomain.com/";
private HttpClient _client;
public PortalWebApiInMemoryTest()
{
var config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "Default",
routeTemplate: "{controller}/{id}",
defaults: new { id = RouteParameter.Optional });
_server = new HttpServer(config);
_client=new HttpClient(_server);
}
Basically in Web API for controller probing to occur the assembly having the controllers should be loaded into memory. In your case if your controllers are defined in the same assembly as your in-memory tests, then the assembly would be scanned for all types which implement System.Web.Http.Controllers.IHttpController.
If your controllers are defined in an assembly different from your tests, then you might need to do additional stuff to make sure to have that assembly be loaded into memory. One example is to create a custom IAssembliesResolver like in the following sample:
http://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/CustomAssemblyResolverSample/ReadMe.txt

AutofacWebApiDependencyResolver usage

What is the usage of the AutofacWebApiDependencyResolver?
I set it like this:
GlobalConfiguration.Configuration.DependencyResolver =
new AutofacWebApiDependencyResolver(container);
But how can I access it in my ApiControllers?
DependencyResolver.Current is not the AutofacWebApiDependencyResolver, its the MVC version.
.Current is available under AutofacDependencyResolver but not under AutofacWebApiDependencyResolver. How can I access the web api version in the web api?
As you showed yourself... use GlobalConfiguration.Configuration.DependencyResolver to access this resolver, same way as you did when you set it initially (it's a static object can be accessed from anywhere in Web API).
Or, use the request dependency scope - wherever you have access to current request (i.e. in MessageHandler):
var myservice = request.GetDependencyScope().GetService(typeof(IMyService)) as IMyService
this will resolve IMyService using the currently set AutofacWebApiDependencyResolver
Try the straightforward way: this.Configuration.DependencyResolver, where this is an ApiController instance.

The request lifetime scope cannot be created because the HttpContext is not available

Having a hard time trying to setup AutoFac with some async non httprequest.
I have the following on App_Start
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterType<sfEntities>().As<IUnitOfWork>().InstancePerHttpRequest();
builder.RegisterGeneric(typeof(sfRepository<>)).As(typeof(IRepository<>)).InstancePerHttpRequest();
builder.RegisterGeneric(typeof(BaseServices<>)).As(typeof(IBaseServices<>)).InstancePerHttpRequest();
builder.RegisterType<EmailServices>().As<IEmailServices>().InstancePerHttpRequest();
builder.RegisterType<UserServices>().As<IUserServices>().InstancePerHttpRequest();
builder.RegisterType<ChatServices>().As<IChatServices>().InstancePerHttpRequest();
builder.RegisterType<DefaultFormsAuthentication>();
builder.RegisterType<WebSecurity>();
builder.RegisterType<Chat>();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
If I change to InstancePerLifetimeScope() I get problems with UnitofWork.SaveChanges(). Setup this way works fine except for async calls.
p.s.: UnitOfWork pass the EF DbContext between services to ensure that the same instance is used and to dispose properly. If I change to InstancePerLifetimeScope I was getting identity conflicts when calling .SaveChanges(), probably because there should be more than one instance of UnitOfWork.
The following code throws the following exception:
Timer timer = new Timer(new TimerCallback(OnTimer), null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
private static void OnTimer(object o)
{
using (var timerScope = AutofacDependencyResolver.Current.ApplicationContainer.BeginLifetimeScope())
{
var chatServices = timerScope.Resolve<IChatServices>();
chatServices.MarkInactiveUsers();
}
}
No scope with a Tag matching 'httpRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being reqested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
On SignalR, the following code throws the following exception:
SignalR.GlobalHost.DependencyResolver.Register(typeof(Chat), () => new Chat(DependencyResolver.Current.GetService<IUnitOfWork>(), DependencyResolver.Current.GetService<IChatServices>(), DependencyResolver.Current.GetService<IUserServices>()));
The request lifetime scope cannot be created because the HttpContext is not available
Thanks in advance!
Having a hard time trying to setup AutoFac with some async non httprequest.
For non-http requests, or more specifically, for non-ASP.NET pipeline requests (like WCF or ServiceStack), you should definitely change all InstancePerHttpRequest() code to InstancePerLifetimeScope(). You can and should do this because InstancePerLifetimeScope() will make it resolvable in both ASP.NET pipeline and non-ASP.NET pipeline contexts.
If I change to InstancePerLifetimeScope() I get problems with UnitofWork.SaveChanges(). Setup this way works fine except for async calls... If I change to InstancePerLifetimeScope I was getting identity conflicts when calling .SaveChanges(), probably because there should be more than one instance of UnitOfWork.
Yes, there should be more than one instance of UnitOfWork, but you can achieve that with a single registration that should be scoped to InstancePerLifetimeScope():
Example:
builder.RegisterType<NhUnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();
The IChatServices service is registered as InstancePerHttpRequest and will therefore only be available within the http request lifetime scope. You are resolving from the application scope which have no "access" to the current request and therefore fail with the error you mention. So yes, to get the timer to work you must register the service in the application scope.
Basically, you can have request scoped services that access application scoped services, but not the other way around.
Question is: what is UnitOfWork.SaveChanges do and what "problems" do you get? Please elaborate.

HttpClient with asp.net WebApi in unit testing scenario

I have an integration test which I wanted to use as the basis of testing my WebAPI controllers with.
Initially I thought I would have to set-up WebAPI in self-host mode and carry-out end-to-end tests over local Http.
However I realised later by looking at the tests in the WebApiContrib project that its possible to set up an HttpClient with an HttpServer set-up with the correct service route to the WebAPI controller. I seems I can unit test the controllers without setting up WebApi in self-host mode. I can put in any domain name in the request on the client and HttpClient seems to auto-magically bind to the correct controller.
Is there any Http transport happening here, using some local interprocess comms or purely 'seeing' that the server is in the same app domain and thus using reflection?
What is happening under the hood for this to happen?
code:
[Test]
public void Test_WebApi_Controller()
{
Assembly.Load("myproj.Web");
var prodServiceMock = new Mock<IProductService>();
ObjectFactory.Initialize(x => x.For<IProductService>().Use(prodServiceMock.Object));
var config = new HttpConfiguration();
config.Routes.MapHttpRoute("default", "webapi/{controller}/{id}", new { id = RouteParameter.Optional });
config.ServiceResolver.SetResolver(new WebApiDependencyResolver());
var server = new HttpServer(config);
var client = new HttpClient(server);
var response = client.GetAsync("http://anything.com/webapi/product").Result;
}
HttpClient has a pluggable pipeline model. Normally when you new up a HttpClient you get a HttpClientHandler instance as the default request processor. That HttpClientHandler is the one actually does the HttpWebRequest. HttpClientHandler derives from HttpMessageHandler.
By no concidence HttpServer also derives from HttpMessageHandler. So in this example the HttpServer is being passed to the HttpClient instance to provide it's request processing. By passing a HttpMessageHandler to the constructor of HttpClient you are telling HttpClient to use the provided handler instead of the default one. If you look at WebRequestHandler in System.Net.Http.WebRequest you will see this is derived from HttpClientHandler and adds some extra functionality that is specific to the Windows Desktop OS.
This means when you make a request to the HTTPClient it is delivered directly to the HttpServer message handler and then processed as it normally would be on the server.

Resources