ActionFilter is not executing in WebApplication but executing in WebApi - asp.net-mvc-4

I have created an ActionFilterAttribute
public class LoggingNHibernateSessionAttribute : ActionFilterAttribute
The purpose of the filter as name indicates is logging and opens and commits a transaction, before and after target action respectively.
I have a WebApi(myAPI) project (MVC4) and a WebApplication(myContent).
Each Api Controller in myAPI is decorated with this attribute.
using myApp.Web.Common.Filters;
namespace myAPI.Web.Api.Controllers
{
[LoggingNHibernateSession]
public class CategoriesController : ApiController
{
When a Http action (Get/Post) is executed inside the ApiController, the ActionFilter gets executed and it works fine as expected.
The problem:
In the WebApplication(myContent), I have decorated those controllers as well with the ActionFilter.
using myApp.Web.Common.Filters;
namespace myContent.Web.Content.Places.Controllers
{
[LoggingNHibernateSession]
public class PlacesController : Controller
{
But here, when an action is executed inside the controller, the ActionFilter is not getting executed.
The ActionFilter belongs to System.Web.Http.Filters;
I have read some posts, and they said to use System.Web.Mvc filters. So I changed the ActionFilter to be from System.Web.Mvc
And when I switched that, the ActionFilter stopped working in WebApi as well.
What am I doing wrong here?

Although WebApi and MVC are very similar and technically consist of largely the same code, WebApi was created by copying all the code rather than through reuse. This happened, I'm told, because the WCF team didn't want a dependency on the MVC assemblies.
Therefore, code (such as your custom filter) compiled against one assembly will not work in the context of the other.
The solution is to duplicate your own code and compile against both sets of assemblies. You could also set up a build system to cross-compile the same code files using different reference assemblies.
It's truly sad when internal company politics result in something like this. The least they could do was acknowledge the problem and add some proper cross-compile support to their tooling, but alas, I digress.

Related

Initializing UserManager<TUser> in class library project

I have an ASP.NET Core 5.0 MVC application and a .NET 5.0 class library called Application.Data. Due to separation of concerns, I decided that the DbContext and migrations should be contained within the data library. The DDL migrations work perfectly, but I'm having issues seeding AspNetCore.Identity users from within the data library.
Simply put, I want to access a UserManager<MyUser> instance in order to invoke the CreateAsync/AddToRoleAsync methods, but the UserManager constructor takes eight parameters that then also need to be instantiated. My understanding is that I could inject the user manager using the AddIdentity method to the service collection of my MVC project, but since my DbContext is contained within Application.Data, I wouldn't be able to run migration commands from within the MVC project.
What is the best course of action here?

Application_Start equivalent in ASP.NET 5

I've come across two methods on the Startup class, ConfigureServices and Configure. Is there an equivalent to the Application_Start method from previous versions of asp.net for doing arbitrary work when the application is starting?
Edit
As a follow up, what are the possible methods that ASP.NET 5 is expecting on the Startup class?
As Simple Man said, there is no direct equivalent method in ASP.NET 5; similar functionality should be started by your services when appropriate in keeping with the Single Responsibility Principle. (The closest is the Configure method, which is where you should probably "start" any services that need to be "started".) However, there is one other method often overlooked in the Startup class: the constructor. Some logic, such as loading config files, may be appropriate there.
You can see how the methods are located on the Startup class in the Hosting repository. Only the two methods you mentioned and the Startup constructor are used.
If I am not wrong from what I understood, there is no such equal method. Rather, there are two different methods, ConfigureService and Configure.
ConfigureService is a method to configure services for your project. The purpose of this method is to set dependency injection for your project. This is the method that will be fired first after constructor has been called.
Configure is a method to configure request pipeline. This method will execute after ConfigureService.
You can refer below two links :
Asp.Net 5 Startup
Asp.Net 5 Startup 2
For your last question, I did not found any other method documentation or declaration in Startup.cs class anywhere online.
You could use IHostedService interface on .NET Core 2.0 .
The IHostedService background task execution is coordinated with the lifetime of the application.When you register your class, you could do whatever you want on starting-stopping phases of application like using Application_Start and Application_End.
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHostedService, MyBackgroundStartupTask>();
}
There is another option available since .NET Core 2.1. An abstract base class we could derive from, named BackgroundService

RoleProvider injection with Ninject

First off I want to say there is a ton of answers on SO and google searches surrounding this, however I'm running into an issue that prevents those solutions from working. The answer here seems to be the way to go. (kernel.Inject(Roles.Provider);)
The issue that I'm having is that when I'm trying to inject the RoleProvider Roles.Provider is null, however my custom provider is found in the list within Roles.Providers. I am thinking that Ninject is trying to access the role provider too soon.
In my NinjectWebCommon class it appears that it's using WebActivator to start itself. [assembly: WebActivator.PreApplicationStartMethod(typeof(Admin.App_Start.NinjectWebCommon), "Start")]
It appears that all of the articles I've come across are using older versions of Ninject and are doing a lot of the heavy lifting in the Global.asax Application_Start... Using my implementation how can I get DI working for a custom role provider?
I'm using the [Inject] attribute within my custom provider.
The WebActivator pipeline runs way before even the standard ASP.NET stack is created. It means that you won't have access to anything created by ASP.NET during bootstrap in NinjectWebCommon.
Use that file only to declare bindings that do not depend on ASP.NET stuff to be up.
In order to get around this issue, you should use Global.asax Application_Start handler to load any additional modules/bindings that are dependend on ASP.NET stuff such as Roles.Provider.
Here is a suggestion that may solve your problem:
public void Application_Start()
{
var kernel = (new Bootstrapper()).Kernel;
kernel.Inject(Roles.Provider);
//Other initialization stuff
}
The Bootstrapper class is a lazy singleton that has a static IKernel initialized within your NinjectWebCommon.cs. So this is the proper way of retrieving the configured kernel instance from outside your NinjectWebCommon.
Give it a try.

How does ASP.Net MVC resolve controllers?

I'm trying to build an asp.net mvc 4 application.
I want the application to encompass both a HTML site and a restful api, e.g.
www.mysite.com/MyDetails/
www.mysiste.com/api/users/{userid}/Details/
In the above example I would use 2 controller classes.
MyDetailsController which inherits from System.Web.Mvc.Controller
DetailsController which inherits from System.Web.Http.ApiController
I've also added a simple 'Users Route' to the WebApiConfig:
routeTemplate: "api/users/{userid}/{controller}/{id}
In my early testing it appears as though the following scenarios are invalid:
www.mysite.com/api/users/12345/MyDetails/
www.mysite.com/Details/
Both of those return a 404.
This is definitely a good thing but what I'm trying to find out is why doesn't it work?
Can I rely on it not working or is it just coincidence in my simple test?
I've read about people struggling to develop a single MVC app/project that encompasses both HTML and REST apis but the most common complaint seems to be you can't duplicate controller names and it still seems like you can't simply use a namespace to differentiate them.
In this example I've deliberately designed the class names to avoid any conflict so what other gotchas are waiting to trip me up?
Thanks,
Chris A
Check your routes file, should be Global.asax under RegisterRoutes. The MapRoute call should tell you everything you need to know for MVC routing. Keep in mind, the order of the routes is important: top routes take priority over the bottom. Web API uses the WebApiConfig class and MapHttpRoute call to configure routes.
Please ensure you have put a (MVC) route on top of the action you wish to hit of your controller, default action being index.
[System.Web.Mvc.Route("Help")]
public ActionResult Index()
{
ViewBag.DocumentationProvider = Configuration.Services.GetDocumentationProvider();
return View(Configuration.Services.GetApiExplorer().ApiDescriptions);
}
Code above will hit this action method (provided your controller is registered and derived either from apiController or Controller) in the following way:
http://localhost:54541/help inside your IISExpress.
To register please do the following:
In "global.asax.cs", you’ll need to add:
AreaRegistration.RegisterAllAreas();

Ninject MVC3 - how does the type gets resolved

Scenario:
I've set up the Ninject MVC3 using the link below:
https://github.com/ninject/ninject.web.mvc/wiki/Setting-up-an-MVC3-application
I followed Nuget version. And, code looks like below:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IService>().<Service>();
}
Could someone help me to understand when and where does the code below gets excuted?
var test=Kernel.Get<Service>();
Basically I'm trying to understand where do we resolve the concrete type.
UPDATE:
my question is more of where does the MVC use Kernel.Get() to resolve the given Interface to the concrete type.
Is this done by Ninject.MVC?
Kernel.Get<Service>() shouldn't be called anywhere. You should request an IService in the constructor of the controller that needs this dependency. When MVC requires this controller then it asks Ninject to create the controller instance and Ninject will inject the service into the controller.