There are many techniques for doing this but they all fell short for us in way or another as we wanted to meet all the following requirements:
- It should be strongly-typed (no using of viewbag/viewdata, thanks - in our opinion it makes it too difficult to refactor views later).
- The views should be bound to the necessary models to enable intellisense.
- It should support ctor dependency injection.
- The common data should be available to controllers and views. This is especially useful when your application supports authentication and you need to show a property of the user in the view and need to use a property of the user in your controller action.
- You should be able to opt-out if necessary.
- Controller actions shouldn't need to change in any way - e.g. no calling of functions to populate the models.
The first step is to define a class that will represent this shared context. There isn't anything special about this class - it's a regular poco.
Here is an example that will store the current user and the number of unread messages in their inbox.
namespace Web.Models { public class SharedContext { public User CurrentUser { get; set; } public int UnreadMessageCount { get;set; } } }
Once you have created your shared context class you need to create a base view model. Again, it's just a poco but what is important is that it is able to hold an instance of the shared context which will be explained in more detail further below. Here is an example:
namespace Web.Models { public class LayoutModel { public SharedContext Context { get; set; } } }
This is the model you will bind to your _Layout file which takes care of the intellisense and "no loosely-typed view data" requirements. In your _Layout, if you would like to show the user's name, for example, you could access the property with @Model.Context.CurrentUser.Name (assuming you had a User class with a Name property, obviously).
The next step is to wire up these classes so they are populated automatically. We start by creating the interface for what I have called the view model factory.
An example of such an interface is as follows:
namespace Web.Mvc { public interface IViewModelFactory { T Create<T>() where T : SharedContext, new(); void Set<T>(T model) where T : SharedContext, new(); } }
The generic constraint ensures that we can access the context properties in the method implementations. Here is an example implementation of this interface:
namespace Web.Mvc { public class ViewModelFactory : IViewModelFactory { private readonly IUserMessageService _userMessageService; private readonly IUserService _userService; public ViewModelFactory(IUserMessageService userMessageService, IUserService userService) { _userMessageService = userMessageService; _userService = userService; } public T Create<T>() where T : SharedContext, new() { var model = new T(); Set(model); return model; } public void Set<T>(T model) where T : SharedContext, new() { var user = _userService.GetCurrent(); model.User = user; model.UnreadMessageCount = _userMessageService.GetUnreadCount(user.Id); } } }
Hopefully it's pretty straightforward. It's an implementation of the view model factory that is injected with several fictitious dependencies and generates a shared context. You will need to use your imagination here a bit.
At this point, you are going to want to register the view model factory in whatever DI container (I hope) you're using. In Unity, you might do something like:
container.RegisterType<IViewModelFactory, ViewModelFactory>(new PerCallContextLifeTimeManager());
Although usually not a fan of inheritance it works well for this scenario. You need a base class from which all your controllers will inherit (instead of from "Controller"). You might have done this already for various other reasons. Here is an example:
namespace Web.Mvc { public class BaseController : Controller { public SharedContext Context { get; set; } } }
In one of your action methods, you could access the current user via Context.CurrentUser.
We want our view model factory to be called automatically so our model is populated correctly. Here is the code for that attribute - you should be able to use this class as-is unless you've renamed the view model factory or shared context.
namespace Web.Mvc { public class LayoutModelAttribute : ActionFilterAttribute { private readonly IViewModelFactory _viewModelFactory; public LayoutModelAttribute(IViewModelFactory viewModelFactory) { _viewModelFactory = viewModelFactory; } public override void OnActionExecuting(ActionExecutingContext filterContext) { var controller = filterContext.Controller as BaseController; if (controller != null) { (controller).Context = _viewModelFactory.Create<SharedContext>(); } base.OnActionExecuting(filterContext); } public override void OnResultExecuting(ResultExecutingContext filterContext) { viewModel = filterContext.Controller.ViewData.Model; var controller = filterContext.Controller as BaseController; var model = viewModel as LayoutModel; if (model != null) { (model).Context = controller != null && controller.Context != null ? controller.Context : _viewModelFactory.Create<SharedContext>(); } base.OnResultExecuting(filterContext); } } }
Taking a quick step back, this is what the attribute is doing:
We override OnActionExecuting and OnResultExecuting as these execute at different places within the asp.net mvc pipeline. To accomplish the requirement of being able to access the share context in a controller, the attribute needs to execute before the controller action; hence OnActionExecuting.
To intercept the model returned from the action and populate the required properties, we override OnResultExecuting which executes after the action has complete but before the view is rendered.
There are two different base-class checks here that allow us to opt-out of the shared context population. If the base class of your controller does not inherit from your new BaseController class, the view model factory will not be invoked before the action executes.
The other check is to ensure that the view model you are returning inherits from the new LayoutModel class. If not, the view model factory is bypassed. This means you can also use the shared context in your non-layout views which can be useful.
The next step is to register this attribute so it executes for every controller. There are different ways to do this, but I generally use the following as part of my site's bootstrapper (where container is our DI container):
GlobalFilters.Filters.Add(container.Resolve<LayoutModelAttribute>(), 1);
The last parameter (1 in this case) is there because I have an authentication filter higher up that should be checked before the new attribute is executed. You are likely to have different requirements in your own application.
Now that the infrastructure is complete, we can get on with building the application. Here is a sample view model that you might use on the homepage of your site:
namespace Web.Models { public class HomeModel : LayoutModel { public string Content { get;set; } } }And here is the controller you might use:
namespace Web.Mvc { public class HomeController : BaseController { public ActionResult Index() { return View(new HomeModel { Content = "Hello View Model Factory!" }); } } }
It might seem a bit complicated at first, but after several large applications this appears to provide the most maintainable and robust solution to this particular problem.
Excellent article. This helped me out immensely.
ReplyDeleteWow, this is exactly what the doctor ordered. One of the cleanest and least-fussy ways of dealing with shared context information between controllers and views. Thanks so much for the write-up!
ReplyDeleteWhat happens if you have a view making use of one of the Contextual properties, but an action that doesn't provide a model, or the model is null?
ReplyDeleteThat's a good point - at the moment, if you supply a model that is null or a model that doesn't inherit from LayoutModel, then none of the contextual properties will be populated. If you wanted this behaviour you would need to make sure any views you rendered from this action did not rely on any property within your shared model.
DeleteThis comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
DeleteI tried to include Ninject specific modifications to the code provided above, but this comment system didn't like the use of greater than and less than characters, probably thought they were HTML, rendering my comments useless.
DeleteHello Rick, could you please send me the Ninject specific modification of this code to my email address? gattish@gmail.com
DeleteThanks in advance.
Where does PerCallContextLifeTimeManager come from?
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteGreat post! Very helpful! How would I pass the controller's HttpContext to the SharedContext Model for creating some shared properties on the SharedContext Model based on that information? I'm using Autofac as my DI Container if that helps.
ReplyDeleteThanks!
Hi Michael,
DeleteWhat I've done in the past is to create something like an IHttpContextFactory and then an implementation that has a single method - something like:
public interface IHttpContextFactory
{
HttpContextWrapper GetContext();
}
and then implement the interface like so:
public class HttpContextFactory : IHttpContextFactory
{
public HttpContextWrapper GetContext()
{
return new HttpContextWrapper(HttpContext.Current);
}
}
Now in autofac you can wire up the dependency IHttpContextFactory to the implementation HttpContextFactory and inject that into your ViewModelFactory.
Inside your ViewModelFactory you can then call GetContext() and use whatever you want from the request/response to set properties on your SharedContext model.
I hope this helps.
Gav
TechnoSoftwar having several years experience working with global customers, connecting our professionals to their business needs, as their IT Development & Support Partner. TechnoSoftwar having a team of dedicated and experienced softwares developers that works for your all business needs. Techno Softwares deals in web design and development, Customized ERPs, CRMs, Web & Mobile Applications, eCommerce platforms etc.
ReplyDeleteGreat Article
ReplyDeleteInteresting Awesome Article
ReplyDeleteASP.NET MVC Training | asp.net mvc training in chennai | Dot Net Training in Chennai | ASP.NET MVC Training in Chennai
Nice blog..Sharing common view model data in asp.net mvc with all the bells and whistles is very easy to understand..Keep on blogging..
ReplyDeletePHP training in chennai
Great and useful article. Creating content regularly is very tough. Your points are motivated me to move on.
ReplyDeleteSEO Company in Chennai
I can feel this is the right way, while I still cannot to finish a sample by myself. Could you give me a whole sample solution. my mail: wangjij@gmail.com
ReplyDeleteWonderful post. I like your post. Keep sharing.
ReplyDeleteppc training in chennai
Wonderful blog.. Thanks for sharing informative blog.. its very useful to me..
ReplyDeleteiOS Training in Chennai
This blog is having the general information. Got a creative work and this is very different one.We have to develop our creativity mind.This blog helps for this. Thank you for this blog. This is very interesting and useful.
ReplyDeleteMobile App Development Company in India
I am expecting more interesting topics from you. And this was nice content and definitely it will be useful for many people.
ReplyDeleteAndroid App Development Company
This looks like the right thing to solve some of my problem in my current MVC 5 project.
ReplyDeleteI using Unity V4.0.1 and Unity.MVC V4.0.1 - both out of the box. All is well until this line of code:
GlobalFilters.Filters.Add(container.Resolve(), 1);
I've tryed adding it in the file UnityMVCActivator in the Start method just below the line DependencyResolver.SetResolver(...
and in the file FilterConfig in the RegisterGlobalFilters method as
var container = UnityConfig.GetConfiguredContainer(); filters.Add(container.Resolve());
and some other places with the same result.
I get squigly lines under Resolve.
What an I doing wrong, Can someone please help me???
Thanks
/Morny
This article is very much helpful and i hope this will be an useful information for the needed one.Keep on updating these kinds of informative things...
ReplyDeleteiOS App Development Company
iOS App Development Company
I wondered upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I’ll be subscribing to your feed and I hope you post again soon.
ReplyDelete<Fitness SMS
Fitness Text
Salon SMS
Salon Text
Investor Relation SMS
Investor Relation Text
Mobile Marketing Services
mobile marketing companies
Sms API
Thanks for your marvelous posting! It is very useful and good. Come on. I want to introduce an get app installs, I try it and I feel it is so good to rank app to top in app store search results, have you ever heard it?
ReplyDeleteVery nice publish! Thanks for the write about. It was very helpful and beneficial.
ReplyDeleteBest web development services in bangalore
BEST web designers in bangalore
I have express a few of the articles on your website now, and I really like your style of blogging. I added it to my favorite’s blog site list and will be checking back soon… wordpress
ReplyDeleteI simply want to give you a huge thumbs up for the great info you have got here on this post.
ReplyDeletePython training in bangalore
Python course in pune
Python training in bangalore
Wonderful article, very useful and well explanation. Your post is extremely incredible. I will refer this to my candidates...
ReplyDeleteJava training in Bangalore | Java training in Btm layout
Java training in Bangalore | Java training in Marathahalli
Java training in Bangalore | Java training in Btm layout
Java training in Bangalore |Java training in Rajaji nagar
Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging.
ReplyDeleterpa training in Chennai
rpa training in bangalore
best rpa training in bangalore
rpa course in bangalore
rpa training institute in bangalore
rpa training in bangalore
rpa online training
Nice tutorial. Thanks for sharing the valuable information. it’s really helpful. Who want to learn this blog most helpful. Keep sharing on updated tutorials…
ReplyDeleteOnline DevOps Certification Course - Gangboard
Best Devops Training institute in Chennai
Woah this blog is wonderful i like studying your posts. Keep up the great work! You understand, lots of persons are hunting around for this info, you could help them greatly.
ReplyDeleteData Science Training in Indira nagar
Data Science Training in btm layout
Python Training in Kalyan nagar
Data Science training in Indira nagar
Data Science Training in Marathahalli | Data Science training in Bangalore
Hello! This is my first visit to your blog! We are a team of volunteers and starting a new initiative in a community in the same niche. Your blog provided us useful information to work on. You have done an outstanding job.
ReplyDeleteNo.1 AWS Training in Chennai | Amazon Web Services Training Institute in Chennai
Best AWS Amazon Web Services Training Course Institute in Bangalore | Amazon Web Services AWS Training in Bangalore with 100% placements
AWS Online Training and Certification | Online AWS Certification Training Course
Nice blog
ReplyDeletejava training in Marathahalli
spring training in Marathahalli
java training institute in Marathahalli
spring and hibernate training in Marathahalli
Nice post..
ReplyDeleteDOT NET training in btm
dot net training institute in btm
dot net course in btm
best dot net training institute in btm DOT NET training in btm
dot net training institute in btm
dot net course in btm
best dot net training institute in btm
Nice post..
ReplyDeletedata science training in BTM
best data science courses in BTM
data science institute in BTM
data science certification BTM
data analytics training in BTM
data science training institute in BTM
Your good knowledge and kindness in playing with all the pieces were very useful. I don’t know what I would have done if I had not encountered such a step like this.
ReplyDeleteangularjs-Training in pune
angularjs Training in bangalore
angularjs Training in bangalore
angularjs Training in chennai
automation anywhere online Training
angularjs interview questions and answers
A universal message I suppose, not giving up is the formula for success I think. Some things take longer than others to accomplish, so people must understand that they should have their eyes on the goal, and that should keep them motivated to see it out til the end.
ReplyDeletepython training in rajajinagar
Python training in bangalore
Python training in usa
Do not waste time winning money right now we have slot games Win an online casino.
ReplyDeleteVery nice post here and thanks for it .I always like and such a super contents of these post.
ReplyDeleteExcellent and very cool idea and great content of different kinds of the valuable information's.
Java training in Bangalore
Thank you for an additional great post. Exactly where else could anybody get that kind of facts in this kind of a ideal way of writing? I have a presentation next week, and I’m around the appear for this kind of data.
ReplyDeleteData science course in bangalore | Data Science training with placement in Bangalore
Superb. I really enjoyed very much with this article here. Really it is an amazing article I had ever read. I hope it will help a lot for all. Thank you so much for this amazing posts and please keep update like this excellent article.thank you for sharing such a great blog with us. expecting for your.
ReplyDeleteSEO Training in Chennai
JAVA Training in Chennai
Big Data Training in Chennai
Selenium Training in Chennai
German Classes in chennai
PHP Training in Chennai
PHP Training in Anna Nagar
This is quite educational arrange. It has famous breeding about what I rarity to vouch. Colossal proverb. This trumpet is a famous tone to nab to troths. Congratulations on a career well achieved. This arrange is synchronous s informative impolites festivity to pity. I appreciated what you ok extremely here
ReplyDeleteData Science Course in Indira nagar
Data Science Course in btm layout
Python course in Kalyan nagar
Data Science course in Indira nagar
Data Science Course in Marathahalli
Data Science Course in BTM Layout
Data science course in bangalore
I adore your websites way of raising the awareness on your readers. Data Centers
ReplyDeleteشركة نفخ المجاري بالقصيم
ReplyDeleteشركة مكافحة النمل الابيض بالقصيم
شركة مكافحة حشرات بالجبيل
Качественная светодиодная лента купить которую вы можете только на сайте Ekodio
ReplyDeleteThanks For sharing Your Information The Information shared Is Very Valuable Please Keep Updating Us Python Online Course Hadoop Online Course Data Science Online Course Aws Online Course
ReplyDeleteThank you for allowing me to read it, welcome to the next in a recent article. And thanks for sharing the nice article, keep posting or updating news article.
ReplyDeletelg mobile service chennai
lg mobile repair
lg mobile service center near me
lg mobile service center in velachery
A bewildering web journal I visit this blog, it's unfathomably heavenly. Oddly, in this present blog's substance made purpose of actuality and reasonable. The substance of data is informative
ReplyDeleteOracle Fusion Financials Online Training
Oracle Fusion HCM Online Training
Oracle Fusion SCM Online Training
Excellent artcle. I have tried same solution with AutoFac and MVC 5.2, it works for GET Action requests and populate common properties defined in SharedModel but during POST actions, SharedModel gets null assignment.
ReplyDeleteNice Post! Thank you for sharing knowledge, it was very good post to update my knowledge and improve my skills. keep blogging.
ReplyDeleteJava Training in Electronic City
hello..
ReplyDeletei really like your blog....
very informative....also helps a lot...
thank you so much for sharing...
keep going on..
https://www.exltech.in/dot-net-training.html
An overwhelming web journal I visit this blog, it's unfathomably amazing. Unusually, in this present blog's substance made inspiration driving truth and reasonable. The substance of data is enlightening
ReplyDeleteOracle Fusion Financials Online Training
Oracle Fusion HCM Online Training
Oracle Fusion SCM Online Training
An overwhelming web journal I visit this blog, it's unfathomably amazing. Unusually, in this present blog's substance made inspiration driving truth and reasonable. The substance of data is enlightening
ReplyDeleteOracle Fusion Financials Online Training
Oracle Fusion HCM Online Training
Oracle Fusion SCM Online Training
Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging.
ReplyDeleteAngular Js training in Electronic City
Download latest audio and video file fromvidmate
ReplyDeleteI want to know more about American eagle credit card login
ReplyDeleteSuperb such good information given keep sharing more thanks for it
ReplyDeletehttps://www.exltech.in/dot-net-training.html
An overwhelming web journal I visit this blog, it's unfathomably amazing. Unusually, in this present blog's substance made inspiration driving truth and reasonable. The substance of data is enlightening
ReplyDeleteOracle Fusion Financials Online Training
Oracle Fusion HCM Online Training
Oracle Fusion SCM Online Training
Best courses in 2019
ReplyDeletebig data and hadoop training in bangalore
data science training in bangalore
machine learning training in bangalore
iot training in bangalore
Flying Shift - Packers & Movers in Bhopal
ReplyDeletevisit here => BEST DEVOPS TRAINING IN BANGALORE
ReplyDeletevidmate app
ReplyDeleteThanks for posting this information. Keep updating.
ReplyDeleteSpoken English Classes in Chennai
Spoken English in Chennai
German Classes in Chennai
Japanese Classes in Chennai
TOEFL Coaching in Chennai
Informatica Training in Chennai
Spoken English Classes in Adyar
Spoken English Classes in Velachery
PPC Service in Delhi
ReplyDeletePPC Companies in Delhi
SEO Company in Delhi
SEO Company in Delhi NCR
SMO Company in Delhi
SMO Company in India
Visit here for more info - Big data and hadoop training in bangalore
ReplyDeleteThanks for this informative blog
ReplyDeleteTop 5 Data science training in chennai
Data science training in chennai
Data science training in velachery
Data science training in OMR
Best Data science training in chennai
Data science training course content
Data science certification in chennai
Data science courses in chennai
Data science training institute in chennai
Data science online course
Data science with python training in chennai
Data science with R training in chennai
Nice Blog
ReplyDeleteFor Data Science training in Bangalore, Visit:
Data Science training in Bangalore
Nice Post
ReplyDeleteFor AWS training in Bangalore, Visit:
AWS training in Bangalore
For IOT Training visit:
ReplyDeleteIOT Training in Bangalore
Nice Post
ReplyDeleteVisit for the Best AI training in Bangalore:- Artificial Intelligence training in Bangalore
Great Article
ReplyDeleteIEEE Projects on Cloud Computing
Final Year Projects for CSE
For AWS training in Bangalore, Visit:
ReplyDeleteAWS training in Bangalore
For AWS training in Bangalore, Visit:- AWS training in Bangalore
ReplyDeleteThanks for your valuable post... The data which you have shared is more informative for us...
ReplyDeleteaws Training in Bangalore
python Training in Bangalore
hadoop Training in Bangalore
angular js Training in Bangalore
bigdata analytics Training in Bangalore
Wow it is really wonderful and awesome thus it is veWow, it is really wonderful and awesome thus it is very much useful for me to understand many concepts and helped me a lot.
ReplyDeletesap s4 hana training in bangalore
sap simplefinance training in bangalore
sap training in bangalore
sap abap training in bangalore
sap basis training in bangalore
sap bi training in bangalore
sap successfactor training in bangalore
sap fiori training in bangalore
This is the exact information I am been searching for, Thanks for sharing the required infos with the clear update and required points. To appreciate this I like to share some useful information.
ReplyDeletesap dynpro training in bangalore
sap fico training in bangalore
sap crm training in bangalore
sap ehs training in bangalore
sap bw training in bangalore
sap hana training in bangalore
sap mdm training in bangalore
sap bpc training in bangalore
It is very good and useful for students and developer.Learned a lot of new things from your post Good creation,thanks for give a good information at sap crm.
ReplyDeletesap hr training in bangalore
sap mm training in bangalore
sap pm training in bangalore
sap pp training in bangalore
sap ps training in bangalore
sap ewm training in bangalore
sap idm training in bangalore
sap testing training in bangalore
I have to voice my passion for your kindness giving support to those people that should have guidance on this important matter.
ReplyDeletesap qm training in bangalore
sap scm training in bangalore
sap sd training in bangalore
sap srm training in bangalore
sap hybris training in bangalore
sap wm training in bangalore
sap hana admin training in bangalore
sap tm training in bangalore
Excellent post for the people who really need information for this technology.
ReplyDeletesap solution manager training in bangalore
sap security training in bangalore
sap grc security training in bangalore
sap ui5 training in bangalore
sap bods training in bangalore
sap apo training in bangalore
sap gts training in bangalore
sap simple logistics training in bangalore