Deploying Multiple Sites on the Same Codebase - Asp.Net, C#, MVC - c#

I recently inherited a solution with about 10 projects in it. 6 of these projects are individual websites that are basically copy/pastes of the original.
This means that any changes that need to be made must be made to each project in order to update all the websites.
What I want to do is have one project for the website code and be able to deploy that code and some configuration settings to create a new website. That way when I make updates to the main Web project I can just deploy to all the websites.
How do people normally approach this? I'll outline my thoughts on it and hopefully some of you can point out better ways to accomplish this or at least give me some affirmation that I am on the right track.
Have a master markup with very general containers.
Allow the users/people setting up the site add widgets to the site which will be assigned to widget placeholders at the top and bottom of all the generic containers.
All styling and colors will be controlled with a stylesheet that can be swapped out.
I know there is some kind of theming you can do. Does this just swap out groups of css and let you configure which one to use in the webconfig?
For elements that will be the same across all sites such as footer images have a naming convention. So if I want Site A to have some footer image I just replace the footer.jpg in the project when I deploy.

Your approach is good.
You should use master markup
Your web system will be CMS
You can use themes to define styles of different projects or you can link css files dynamically
if they are really copies of each other than you can make it very general by defining all of them as one website and put all the settings of css images markups in database
If you don't want to make everything very generic you can make web user controls and load them dynamically at run time according to the project (Remember, you can load WebUserControls at runtime using the LoadControl method)

That's unfortunately a question that is likely to get the response 'It depends' as each of those approaches could be used or not used dependent on the needs of the project. If the projects only vary by presentation then master pages combined with CSS would make a reasonable solution.

Related

MVCSiteMapProvider won't use Razor Templates for Menu

I'm enjoying using the well-made MVCSiteMapProvider through Nuget at the moment but I've hit a roadblock.
I'm trying to modify the template for the #Html.MvcSiteMap().Menu() helper. The file I'm modifying is ..\Views\Shared\DisplayTemplates\MenuHelperModel.cshtml and no matter what change I make to the file, the template does not update when rendered.
I've done a Find All with notepad++ and found that within MvcSiteMapProvider.dll there is two templates, one for classic asp.net and one for Razor. So clearly the template within the .dll file is being called - but how do I make this not the case?
It may be worth knowing that although the templates are located in ..\Views\Shared\DisplayTemplates\, the site is configured to use a different folder for Views.
edit: also if I pass in a template name to the helper, still no effect.
Templated helpers are an MVC creation, not one of MvcSiteMapProvider. I strongly suspect your issue is due to reconfiguring your Views folder. MVC does not support a way to reconfigure your templates folder.
But as pointed out in the accepted answer, it is possible to put them under ~/Views/CurrentController/DisplayTemplates/. You might be able to use that feature to put the templates in your newly configured folders. This means that you would need to add a copy of the templates for every single controller, though.
The best solution is not to change the MVC folders from their defaults.
If that is not an option, you might consider rolling your own Menu HTML helper based on the code from the current one that returns an HtmlString rather than using templates.
The templated helpers are better because you can edit the code after it is deployed (which is why we did it that way), but it comes with the caveat that you have to rely on MVC's default folder structure to use them.

How do I integrate a new MVC C# Project with an existing Web Forms VB.NET Web Application Project?

We have a corporate website with a large amount of dynamic business application pages (e.g. Shopping Cart, Helpdesk, Product/Service management, Reporting, etc.) The site was built as an ASP.Net Web Application Project (WAP). Our systems have evolved over the years to use .NET 4.5 and various custom business logic DLLs (written in a mix of C# and VB.NET). However, the site itself is still using VB.NET Web Forms. We now have done a few side projects in MVC 4 using Razor/C#, and we want to use this framework for new pages on the main corporate site going forward. What would be the easiest way to achieve this?
I found this nice list of steps to integrate MVC 4 into an existing Web Forms app. The problem is that because our existing app is a VB.NET WAP, it compiles into a single DLL, and .NET allows only one language per DLL. The site is way too big for us to contemplate converting it to C# all at once (yes, I've looked at the conversion tools, and they're good, but even 99% accuracy would leave us a huge amount of cleanup work.)
I thought about converting the existing WAP into a Web Site Project (WSP) which does allow mixing languages and then following the steps above, but after a few pages of Google results, I couldn't find any steps for converting a WAP to WSP. (Plenty of sites offer the reverse steps: converting a WSP to a WAP.)
Another idea I had was to create a completely separate MVC project, and then somehow squish them together into the same folder structure, where they would share the bin folder but compile to separate DLL's. I have no idea if this is possible, because certain files would collide (e.g. Global.asax, web.config, etc.)
Finally, I can imagine a compromise solution where we keep all the MVC stuff in its own separate application under a subfolder of the main solution. We already use our own custom session state solution, so it wouldn't be difficult to pass data between the old site to the new pages.
Which of the ideas above do you think makes the most sense for us? Is there another solution that I'm missing?
After some more research and experimentation (and thanks to a suggestion from T.S.) I have narrowed it down to either the 2nd or 4th option from my initial question:
Convert our WAP to a WSP, and then follow the steps to integrate MVC into the site. I don't see moving from a WAP to a WSP as a complete step backward. As the MSDN link explains, performance does not suffer, and it's mainly a question of how to adjust our build/deployment process. The major advantage with this technique is that it allows multiple languages to coexist in the same project and root folder. Certain files, such as Global.aspx.vb, would have to remain in VB.NET. But specific folders and web pages could be designated as C#. The disadvantage for us is that our site has a lot of legacy pages that use old-style server-side-includes of ASPX page fragmets, and these cause build errors in a WSP. These would have to be changed into User Controls, or perhaps renamed to an unrecognized extension, such as .aspxinclude, so that they are not included in builds.
Create an MVC child application as a new .NET project (see http://support.microsoft.com/kb/307467). The parent web.config needs its <system.web> section wrapped with <location path="." inheritInChildApplications="false">, and the new app's subfolder needs to be converted to an Application via IIS Manager. The child app can be a WAP using a different default language (C# vs VB.NET). This makes it is easier to isolate from our existing project. But this is also a disadvantage because the MVC routing only works on URL's in the subfolder of the child application. So if we wanted multiple parts of our site to use MVC routing, it would require separate child projects, e.g. (/cart, /myaccount, etc.)
We are probably going to go down the path of option #1, converting to a WSP, and only resort to #2 if we encounter a big obstacle.
UPDATE: I was able to do the conversion using technique #1. It's been working for several months now, so I published a blog post with the procedure I followed.
Came up with a very simple solution.
Create new MVC C# project
Add the old vb project to the solution.
Move the VB aspx pages to the new C# project
REMOVE THE CODE BEHIND ATTRIBUTE FROM THE FIRST LINE OF THE VB PAGES eg...Codebehind="ProductDetails.aspx.vb" (this is the magic)
Add a reference to the VB project in the C# project
This will work for master pages as well
Strangely the VB aspx pages 'just find' the codebehind from the reference and the C# project does not seem to care about the aspx pages being VB.
Go figure!
Hope I saved someone some time. I spent many hours on this.
You have 3 options here:
Convert the ASP.NET Web forms from VB to C#
Convert your MVC 4 written in C# to VB.
Develop all old apps in ASP.NET Web forms again to MVC 4 (ugly but better for future changes)
My advise is keep them diferent projects only share your business logic. And in the same solution file.

Two Sites from one project in Visual Studio

We're publishing two websites based out of one project.
The main site is a asp.net web forms web application, written in c#. The next one we are creating will derive from this. We want to be able to maintain both sites by editing the same code.
So we don't have to edit simple changes in both projects.
The difference between the sites, are the css file(and maybe the master page).
And some dependant code, like f.ex. login.
I figured I could do this using different build configurations.
First of all:
Is this a good way to solve it?
If yes:
How do I create a web.config file to load a different settings?
How do I load different css file(and different master page).
How do I create dependent code?
If no:
What would be?
Thanks for any help and tips contributed.
The css files you can change it on application_start event (assuming that you have two different host for the application).
You can change the master page at preInit event of page.
The better approach can be
Create you business logic in a separate project.
Try to create different Theme for different Client.
Set the theme on Application_Start event.
You can also take advantage of DI (dependency injection) to call different method of different classes.
You would be better off creating two projects, but creating shared code as a dll that both projects can share.
I've worked on custom web CMS and therefore i have to create two websites doing some common functionalty. Here are my steps
Create a solution.
Add a class library type project
Add two different websites
Give reference of class library to both websites and you are good to go.

Merge sitecore project with another .net project

I have a unique requirement which I need to meet to with sitecore, and I was wondering if it is feasible. The client has an existing .net solution, which is a web project (web site, not web application) that is built on the spring framework and commerce server. They now want to use sitecore to enable content editing on 'some' of their pages. THe requirement is that they do not want to maintain the master pages and any common items in sitecore, but they want sitecore to be able to use the master pages and all the controls they have in their custom solution. I've checked through their project, and they have a LOT of dependencies on many other references and projects, and so it is not a fairly simple application. They do not want to have the master pages specifically in sitecore, and they only want sitecore for the main content editing. They basically want all the layouts in sitecore to use their master pages. I've tried using virtual directories and then using the master pages in sitecore, but there are way too many dependencies in their project. I've tried to make sitecore an application within its own directory, but it doesn't seem to work very well. I can merge the web.configs as much as I can, but that is going to cause headaches down the road when its time to upgrade...My more high level question is, is this doable at all, and if there is a way I can meet this requirement.
Initial thoughts are that using master pages within Sitecore is bit of a non-starter. It seems odd to have such requirements and have Sitecore already prescribed.
Three ideas come to mind.
1) Consider keeping the solutions separate, and host certain Sitecore pages in a clean, standard, Sitecore solution. Use a load balancer to direct which urls point where. There could be many side effects to this approach to do with sessions etc.
2) Migrate the existing solution to Sitecore replacing master pages with Sitecore layouts and sublayouts. At the same time, migrate to a web application project. This is very likely the best long term approach. The main challenge would be mapping existing content to a set of templates in Sitecore, and various bits of refactoring.
3) Use Sitecore as a content repository, but serve content from your existing web site solution. This will have numerous complicating factors due to lack of a typical Sitecore item, site & domain context which would all need to be handled by custom code. The solutions could be entirely separate, and even use web services to retrieve content from Sitecore which is served by the existing solution. It gives full separation, but you loose a large chunk of Sitecore functionality and end up with an expensive rich text editor + database.
I'd opt for #2 where possible.
I think I can see a few options on how to do this. I'm currently doing something similar right now on a large enterprise project where there's an existing ASP.NET MVC application running the bulk of the site. Here are some options I can think of:
Use a sub-domain for the Sitecore-only stuff and <iframe> in the Sitecore content or do an HTTP GET to the Sitecore pages and pull the content into the existing app. E.g. sc.mysite.com is the Sitecore app. I'm currently doing this with MVC now and its fine. From a content management POV, editors can still use Page Edit mode on the Sitecore pages in their stand-alone state but the content is in production in the fed in state on the main MVC site.
Sitecore can use MasterPages, it just defeats the purpose of the presentation layer of Sitecore. Essentially, you can have your Sitecore layout inherit from the MasterPage and it works just like any normal application would with inheritance. I'm not sure of the caching implications though. As long as your app references the Sitecore assemblies, you can use the API as long as its part of the Sitecore context. If you DO use MasterPages with Sitecore, make sure you add a placeholder with the key webedit to allow page editor to work: <sc:placeholder key="webedit" runat="server" />

ASP.NET Web User Control Library

We have a bunch of user controls we would like to pull out of a web application and into a separate assembly/library, and I thought it would be as simple as creating a class library and pulling the ascx and ascx.cs files into the project, and compiling a DLL to be reused among our applications.
This was not the case, however.
Our ultimate goal is to have a single distributable DLL (similar to how Telerik distributes their controls) that we can throw into any web application. The steps here: Turning an .ascx User Control into a Redistributable Custom Control were very simple to follow, however this results in many files named controlname.ascx.guid.dll, which is not the desired result. I couldn't even get these to work anyways, since we have additional classes that need to be compiled into the assembly.
Has anyone successfully created a web user control library in .NET (we're using 3.5 here)? I can't seem to find a nice step-by-step guide.
I realize this is an old topic, but if anyone is looking for a solution for creating reusable user control libraries, it turns out it's fairly simple. Here are two good step-by-step guides along with source code:
From MSDN: Turning an .ascx User Control into a Redistributable Custom Control
From Code Project: Straight way to create ASP.NET user controls library
The second link provides a solution to the multiple dlls created by the first link.
Edit- (2) Seems to be a dead link. Here's the new link
https://www.codeproject.com/Articles/30247/Straight-way-to-create-ASP-NET-user-controls-libra
If you want to share controls among project, my experience has shown that the best way is to build custom asp.net server controls instead of usercontrols. User controls are good for sharing within the same project, but not over multiple ones.
For this purpose I suggest you to build a set of custom server controls inside a class library and use that on all of your projects.
This book does quite a good job at explaining the basics of creating server controls
Edit:
I'm currently developing a .net web server control library. I actually didn't follow any step-by-step guide. I mostly considered using the book I mentioned above and the MSDN library + Reflector, which is a great tool for inspecting existing MS server controls and learning from them.
I found the tutorial Creating and Using User Control Libraries but it seems like a bit of a hack as it relies on a post-build command line event to copy the user controls from one project to another.
Somewhat late, I admit.
To create a re-usable library of user controls; create a new Web Application Project, delete all the scaffolding, add a (number of) user control(s). Create a Web Deployment Project from the Web Application Project, in the WDP properties choose the option to Merge all control output and assign a name for the library and ensure that Allow this website to be updatable is NOT checked.
Build the WDP and use Reflector to examine the generated library; you'll see that it contains an ASP namespace and the types you carefully crafted have been renamed i.e. usercontrol_ascx. In your target website(s) add references to BOTH the output dlls from your WDP, add a system.web/pages/controls node to web.config using the namespace ASP and the name of the assembly that you defined in the WDP.
Now when you use the library in a page (for example) you must use the alias that you defined in web.config and the typename as seen in Reflector i.e.
<ucl:usercontrol_ascx ... />
I found it useful to add a dependancy for the website(s) on the WDP so that the WDP is built before the websites; now I can change the user controls in the WAP without having to remember to build the WAP before building the website(s).
I hope that someone finds this useful as it cost me a few grey hairs getting to this stage and still have VS do its 'automagically' thing.

Categories