Recently created my first httpmodule. It drops and manages a user cookie. This all works fine.
I now need to drop another cookie relating to site affiliates.
The question is, is is better practice to create 2 entirely separate httpmodules or add extra code to the existing one. The reason I ask is because the functionality is closely related (they both drop a cookie).
Why not write a Class Library that deals with cookies, then write your HttpModules that use the Cookies Class Library?
I don't believe you should join them, because they set cookies for different reasons, and it's easier to disable them individually if they aren't in the same module.
Related
I am using ASP.NET MVC and have to develop and deploy multiple websites based on a first website.
There are variation in some controllers, some views, some scripts and some models, and the Database are different on each website (mainly columns are differents but table names remains the same).
Is there a way to handle such a thing in a single Visual Studio Project, in order to make maintaining easier, and be able to add common feature easily on every website ?
Currently, I copy the pilote project into a new VS project, and change all the variation. But I find it's not an ideal situation (because of maintaining/improving).
I have implemented something like that years ago and can give some general advice you might find useful.
First of all developing app with such "multitenancy" has nothing to do with MVC pattern itself. You can do that without MVC :D. Second, if the websites supposed to work with different business domains I am afraid there is no generic way to do what you want. In my case it was just a number of e-commerce platforms.
Anyway, consider next things.
1.Think about using sub-domain approach if you can. It will free you from stupid routing and cookies shenanigans. Basically you can map *.yourdomain.com to one app and handle the necessary logic related to tenant easily. So in my case it was an application that behaved differently depending on provided url, not route, but sub-domain, 'superclient.yourdomain.com' for example. Its not always possible or good idea, but think about it.
2.Dependency Injection everywhere. Well, its useful in general but in your case is absolute must have - try abstract any tenant specific logic in separate types and init them in one place. Its everything related to localization, timezone settings, app theme, branding info on the app header etc. Just initialize and inject where its needed. If you have something like
if (website1) {
showBlockOne();
} else if (website2) {
showBlockTwo();
} else if (website3) {
showBlockThree();
}
then you doing something wrong, its a road to insanity. It should be something like
_currentTenantViewContext.ShowBlock();
So its polymorphism over conditional operators in most cases.
3.In my case the requirement was to create an app which can work with any language so I had to handle that issue on database side as well. The problem is that if usually you have lets say for example ProductType table in database with Id and Name, in multitenant application its not that simple. My solution was to create two tables - ProductType with Id and Code fields and ProductTypeLocalization table with Id, ProductTypeId, LanguageId, Value fields to handle this problem. Requirement also was to make this values editable from admin panel...
I don't know is it the case for you, but if yes think about it before the shit hits the fan in future.
4.For situations where you need some specific fields in some database table only for one site its not a good idea to spawn them freely (in general). Consider using some generic format for that, like JSON or XML. If you have few additional text fields for specific website in some table just create one field (call it ExtraSettings or something) and store this strings as JSON in that one field. Of course you have to handle this data in separate way, but its about dependency injection again.
Also you can use NoSQL for that.
5.Provide feature toggling, different websites requires different blocks to be displayed, rules applied etc. You have to have some way to on/off them for particular website(tenant) without recompile/redeploy.
Hope it helps.
I need to store an ID against a user that will be used in EVERY action that is carried out on my web application. I had hoped to use a customized authorization ActionFilterAttribute (on an entire controller) to populate the ViewData with this additional info, but it turns out that a whole STACK of stuff runs before these ActionFilterAttributes do e.g. ModelBinding, Controller construction
I thought perhaps there may be a way to extend the HttpContext.User.Identity to store additional data but have no idea even where to start.
Any ideas?
SOLUTION
Looking around in more detail on StackOverflow I came across this solution that does EXACTLY what I want and in a super clean and proper way (HINT: It uses the userData property of the FormsAuthenticationCookie - https://stackoverflow.com/a/10524305/175893
One option is to have a global (static) ConcurrentDictionary and store any additional information regarding the identity/user there - use whatever is convenient as a key... since this dictionary is thread-safe and implemented mostly lock-free it provides excellent performance... this way you don't need to mess around with any ASP.NET-specific stuff...
I have some code used to determine if a user is logged in and I want to put this on every page in an ASP.NET website so that only logged in users can view it. The problem is that the site is split into multiple projects/solutions so maintaining the single piece of code might be hard.
I was thinking I could create a class that inherits for System.Web.UI.Page and overrides Page_Init, but that would require changing all pages so they inherit from new new class. Also I don't think this will work across projects.
So then I thought approaching the problem from a different side: using AOP. I have never used Aspects before but it looks like I could use PostSharp to write an Aspect that injects code before every Page_Init (or maybe Page_Load?). This might work as a quick solution but I might run into problems if I need a page to not perform the authentication check (available to everyone).
Just to clarify, I already have a login solution; I am just looking for a checking that login on each page.
Look into HttpModules. The asp.net framework is already programmed so that a module runs on every page request, you just have to write it and add it to web.config.
http://msdn.microsoft.com/en-us/library/zec9k340(v=vs.71).aspx
EDIT: Here's a better link that demonstrates handling the BeginRequest event
http://msdn.microsoft.com/en-us/library/ms227673(v=vs.85).aspx
As #jrummell mentioned, there's MembershipProvider which is a great option, but if you're creating custom login solition, check this link which has a pretty simple login implementation step by step
Since you seem to have your login solution handled and working, creating a class that overrides the page_init sounds like your best option. This can work across other projects by simply creating that class in a separate project that you can included in your other solution(s)... To be honest, that's the easiest way to span the logic across multiple projects.. This will also be easily maintained because you'd only have to update one location going forward.
If you are using MasterPages, you wouldn't have to hit all of the pages, you could just include it on specific MasterPage(s) and set all the pages you want authentication to use that MasterPage.
Windows Identity Foundation can solve this for you. See http://msdn.microsoft.com/en-us/security/aa570351 for details on WIF. No need to reinvent the wheel. If you had only one Web application, Forms authentication would suffice.
I want to know if its possible and how to do the following , i have a basic MVC application (ASP.Net) that i have modified to work for me. Now the application already handles authentication perfectly fine but i need to use this authentication in another app.
Without creating a webservice is it possible for me to make calls to the applications authcontroller , if so how
You can't directly call a controller in another application because it is in a separate AppDomain. If you just want to reuse the existing code, you could refactor it into a separate assembly (library project), include that assembly in your new application, and just reference it from your logon controller. If you are trying to do single-sign on, then you may want to look at existing SSO solutions, such as JA-SIG CAS 2.0.
Authentication is a cross-cutting concern that shouldn't be embedded into a single use case/controller. AOP afficionados would say it should be encapsulated in an aspect.
Whoa guys slow down , im still beginning MVC and all its related details , the single sign on looks promising , the reason i dont want to go that route yet or even refactor the code and include it in the second project is because its way too simple a project.
Using a configuration file I want to enable myself to turn on and off things like (third party) logging and using a cache in a C# website. The solution should not be restricted to logging and caching in particular but more general, so I can use it for other things as well.
I have a configuration xml file in which I can assert that logging and caching should be turned on or off (it could also be in the Web.Config, that's not the point right now) which will result in for example a bool logging and a bool caching that are true or false.
The question is about this part:
What I can do is prepend every logging/caching related statement with if (logging) and if (caching).
What is better way of programming this? Is there also a programming term for this kind of problem? Maybe attributes are also a way to go?
Why not just use the web.config and the System.Configuration functionality that already exists?
Your web app is going to parse web.config on every page load anyway, so the overhead involved in having yet another XML config file seems overkill when you can just define your own section on the existing configuration.
I'm curious what kind of logging/caching statements you have? If you have some class that is doing WriteLog or StoreCahce or whatever... why not just put the if(logging) in the WriteLog method. It seems like if you put all of your logging caching related methods into once class and that class knew whether logging/caching was on, then you could save your self a bunch of If statements at each instance.
You could check out the Microsoft Enterprise Library. It features stuff like logging and caching. The logging is made easy by the fact you always include the logging code but the actual logging beneath it is controlled by the settings.
http://msdn.microsoft.com/en-us/library/cc467894.aspx
You can find other cool stuff in the patterns and practices group.
Consult http://msdn.microsoft.com/en-us/library/ms178606.aspx for specifics regarding configuring cache.
I agree with foxxtrot, you want to use the web.config and add in a appsetting or two to hold the values.
Then for the implementation on checking, yes, simply use an if to see if you need to do the action. I highly recommend centralizing your logging classes to prevent duplication of code.
You could use a dependency injection container and have it load different logging and caching objects based on configuration. If you wanted to enable logging, you would specify an active Logging object/provider in config; if you wanted to then disable it, you could have the DI inject a "dummy" logging provider that did not log anything but returned right away.
I would lean toward a simpler design such as the one proposed by #foxxtrot, but runtime swapping out of utility components is one of the things that DI can do for you that is kind of nice.