asp.net mvc - common code to execute when loading any page from the application - asp.net-mvc-3

Where would such code go? Is there a commonly executed block inside Asp.net mvc 3 application - something that gets executed every time any page is loaded?

You can do this by two ways:
First, you can inherit a base Controller from System.Web.Mvc.Controller. Then you use this base class inherits for your application. By this way, you can handle all action executions by overriding OnActionExecuting method of your base controller.
Second and better solution is using Custom Action Filters. Create a custom filter and register it globally in Global.asax file like this:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new YourCustomFilter());
}

Global.asax (ex: http://www.dotnetcurry.com/ShowArticle.aspx?ID=126) or inside the _Layout, it depends on what you're doing.
Just so you know the Global.asax file is also available in ASP.NET Webforms.

Related

One resource file per language for entire asp.net core project

Is it possible to just have only one resource file (per language) for the entire project in stead of per controller and per view (as mentioned in the manual https://docs.asp.net/en/latest/fundamentals/localization.html)?
A resource file per controller and language seems a bit overkill.
Yes, that is possible. You've to override StringLocalizer and StringLocalizerFactory. With those custom you can store resource in one or many files, in the database or in the JSON files. Or do other magic...
And then all you need to do is to register your custom service:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IStringLocalizerFactory, YOUR_LOCALIZER_FACTORY>();
}

Use Container/DependencyResolver in other dll

I'm trying to get myself familiar with MVC3 and autofac but I've encountered small problem that I'm having trouble resolving.
I am using autofac integrated with MVC3 and all works well, pages are loading correctly, dependencies are being injected and that's cool. What's bugging me is how to use autofac's Container or MVC's DependencyResover in class library project.
I'm trying to create static class that will help me handle domain events. I simply want to be able to call the method with event parameter and everything should be handeled by this class. Here is code:
public static IContainer Container { get; set; }
public static void Raise<T>(T e) where T : IDomainEvent
{
foreach (var eventHandler in DomainEventManager.Container.Resolve<IEnumerable<EventHandlers.Handles<T>>>())
{
eventHandler.Handle(e);
}
}
As you can see it's pretty straightforward and everything would work great if it wasn't MVC approach. Some of my dependencies are registeres as InstancePerHttpRequest (NHibernate' session), while other are registered as InstancePerDependency or SingleInstance. Thus when I try to use container created in my UI project, I get exception that there is no httpRequest tag available.
How can i reuse the Container created in web project to get access to all of it's features, including InstancePerHttpRequest and httpRequest tag?
Or maybe there is other solution to my problem? I was thinking about using delegate function to obtain event handlers, but I cannot (can I?) create generic delegate that I would not need to initialize with concrete type at time of assignment.
Why I want to do this using static class is basically every entity and aggregate or service needs to be able to raise domain event. Injecting EventManager into every one of these would be troublesome and static class is exactly what would resolve all my problems.
If anyone could help me get my head around it I would be grateful.
Cheers, Pako
You shouldn't be referencing your container directly from your app code. This looks like the Service Locator anti-pattern. The correct action is to pass your objects the services they need to do their jobs, usually done through constructor parameters. BUT... if you are going to insist on depending on a global static, then at least model EventManager as a singleton, such that usage would look like:
EventManager.Current.Raise<SomeEvent>(someObject);
and then you can set EventManager.Current equal to a properly constructed instance when your app is initialized.

Setting Session in MVC3 when the class not inherited from controller or helper

I would like to write and read data to Session even if my class not inherited from controller or helper. Something like this:
public class User
{
public void CreateSession()
{
Session["key"]=data;
}
public void ReadSession()
{
data=(string)Session["key"];
}
}
Important thing - I need to get instance of User class in some actions
and views. Am I be able to inherit User class from controller or
helper. Because I've already try that, but I got some errors.
How can I achive this?
Thanks in advance.
HttpContext.Session will work, it's a static available anywhere to an assembly that references System.Web.
If your code is in your main website assembly, this should work well. If it's not, you'll have to create a dependency on System.Web which you may or may not want to do.
You should do these kind of things in your controller.
You can access HttpContext directly, but that's not "the ASP.NET MVC way", and you loose some of the advantages of using MVC in the first place. Like making testing harder, and directly coupling your application to HttpContext...
Also, if it's a new session, or Session["key"] is not set for some reason, data=(string)Session["key"]; would throw a null reference exception.

How to stop Ninject from overriding custom DataAnnotationsModelValidatorProvider?

I have a custom DataAnnotationsModelValidatorProvider for doing model validation in a more dynamic way then just adding attributes. I tried to add my provide to the global.asax.cs like so:
ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add(new AttributeValidatorProvider());
But once I load my form, I get an error saying "Validation type names in unobtrusive client validation rules must be unique. The following validation type was seen more than once: required".
According to a comment on this blog, this is because Ninject is overriding custom validator providers.
I'm fairly new to MVC and I can't seem to find a way to tell Ninject to accept my custom providers as well, how would I go about fixing this problem?
For the record: I do not wish to use Fluentvalidation.net, I want to stick with the default MVC validations (for the most part).
There is another way (works in MVC 4 for sure):
Find your class which inherit IdependencyResolver interface and add to constructor _kernel.Unbind<ModelValidatorProvider>(); - you just unbind ninject validator and there should be no colission with default validator.
In my case my constructor looks like this:
public NinjectDependencyResolver()
{
_kernel = new StandardKernel();
_kernel.Unbind<ModelValidatorProvider>();
AddBindings();
}
Change the registration of the provider to
Rebind<ModelValidatorProvider>().To<AttributeValidatorProvider>();

MVC3 Action Filter Using Database (EF 4.1 DBContext, Ninject)

I'm trying to setup an 'Authorization' Filter on an Action, creating my own ActionFilterAttribute where I do a database lookup to determine if a user has access to a certain resource.
On my class inheriting from ActionFilterAttribute, I have created an Injected(Ninject) property to hold the service that I am using for the database access. I have a parameterless constructor so that I can use this as an attribute on my actions. In the 'OnActionExecuting' Method, I am able to gain access to the Injected property (it's not null), but the base DBCotext that it is using is closed.
This working fine, up until the RTM of MVC3, where the Release Notes stated:
Breaking Changes:
In previous versions of ASP.NET MVC, action filters are create per
request except in a few cases. This
behavior was never a guaranteed
behavior but merely an implementation
detail and the contract for filters
was to consider them stateless. In
ASP.NET MVC 3, filters are cached more
aggressively. Therefore, any custom
action filters which improperly store
instance state might be broken.
The first time I use this filter, it works as expected, but if I refresh the page or another user access this filter, I get the error:
The operation cannot be completed
because the DbContext has been
disposed.
which is what I guess I should expect given the breaking changes notes.
My question is this, what would be the preferred/recommended way of accomplishing what I need to do? Should this be in an ActionFilterAttribute, or should this 'authorization' be done somewhere else?
I'd do authentication in Application_AuthenticateRequest and authorization in your attribute using Thread.CurrentPrincipal, but your method should work too. You just need to count with fact that DbContext will be different for each request but your attribute won't. Something like this should do the trick (I'm assuming you are using DependencyResolver):
public class MyMightyAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var context = (DbContext)DependencyResolver.Current.GetService(typeof(DbContext))
// authenticate, authorize, whatever
base.OnActionExecuting(filterContext);
}
}
I have been battling with this for a while and finally solved my problem. So here is my solution in the hope it may help someone else.
The setup:
1. I have an MVC3 project, a custom action filter that accesses the db using EF5 via a business service.
2. I use Unity and unity.MVC to resolve my dependencies on a per request basis.
3. I use property injection into my custom Action filter, as it has a parameterless constructor.
The result.
Dependency injection works correctly for all the services used by actions, my EF DbContext is correctly disposed of at the end of each request.
The Problem
Although my property dependency is resolved in my custom action filter, it contains a stale instance of my DbContext (e.g. it seems to have been cached from the previous request)
As mentioned in previous posts, MVC3 is more aggressive with filter caching and the state of a filter cannot be relied on. So the suggestion was to resolve the dependency in the OnActionExecuting method. So I removed my injected property and did just that called resolve on my unity container. However I still got a stale version of the DbContext. Any changes in the DB were correctly queried in my main actions, but the custom action filter didn’t pick them up.
The solution.
Unity.MVC Manages per-request lifetime by using child containers and disposing these at the end of each request. By resolving my dependency’s in the action filter from my unity container I was resolving from the parent container which is not disposed of on each request.
So rather than
IoC.Instance.CurrentContainer.Resolve<IService>();
I used this to obtain an instance of the child container rather than parent.
var childContainer = HttpContext.Current.Items["perRequestContainer"] as IUnityContainer;
var service = childContainer.Resolve<IServcie>();
I'm sure there must be a clean way to achive the same result, so please add suggestions.
Ok slight refinement to allow my unit test to inject a mock of the service.
1. remove the dependency resolve from the the OnActionexecuting and add two constructors.
public MyCustomActionfilter() : this(((IUnityContainer)HttpContext.Current.Items["perRequestContainer"].Resolve<IService>())
and
public MyCustomActionfilter(IService service)
{
this.service = service;
}
Now the constructor resolves your service and stores it as a private readonly. This can now be consumed in your OnActionExecutng function. Unit tests can now call the second constructor and inject a mock.

Resources