The Scenario :
I have my main base MVC project, with the model + view + controller that I want to re-use in my children MVC projects. But the children MVC projects's CSS styles are all different, and uses different localization resource files.
The question:
Is it possible to create such an MVC child project that references the parent MVC project, but uses different styles etc? The only difference between the projects are the styles and localization.
Or will I have to keep the views separate in each child project? (this feels like a waste because all the projects views will have the same code)
I am using TFS, so I don't think "File Linking" is an option
Regards
David
I see two ways:
Calculate main css file based on domain name (or other projects differences) and use it in view where css include to HTML
Create two views packs and switch it in projects (in addion you can change HTML in projects)
For example first way you may look http://www.getpets.me/ and http://www.getalljobs.com/ sites. They use one instance of code, but include different css files.
I only tested this briefly, but it seems to do the trick :
MvcApplicationRazorGeneratorSeparateLibrary.
There is a zip file you can download and test
This means you have two MVC projects, the main one creates all the views etc and compiles it.
Then you can reference it from the second MVC project, and only change the styling, content, web.config or add views in the second MVC project.
Related
How can I go about separating my MVC project into UI specific (JS, CSS, Images, Fonts, and maybe Views) and Controller/Model specific (Controllers, Helpers, Models, and may be Views). Since our front-end developers work mostly independent of Visual Studio, I was looking for best practices in separating projects. Any pointers or sample projects?
This is how we finally ended up doing it.
Create a separate visual studio project called SolutionName.Client (this is where all frontend js and scss files go)
Create you MVC project called SolutionName.MVC (this is the asp.net mvc project)
Using Grunt.JS write tasks that compiles all js and css files and drops them to SoltuionName.MVC/Content folder
Similarly write tasks that drops all Views (razor files) into SolutionName.MVC/Views folder.
In Project build settings, add a pre-build tasks to run grunt task.
This setup took few hours to get it working but it is now quite useful.
You can easily do this and I've done it for each of my projects in MVC as well.
One project has your Controllers, ViewModels, and in my case, any custom logic related to Dependency Resolution for MVC and custom classes related to security authentication with MVC. Basically any code that touches the MVC framework core and is not involved in rendering content.
The other one has pretty much everything that you use on the client-side, and code needed for the front end. Which in my case, code-wise, is very minimalist and included some code for Glimpse and Elmah. The rest is your Views, Styles, Scripts, static content like downloads, etc.
As for the files in App_Start, My views project has Bundles, Filters, and obviously any HtmlHelpers you may have, custom css transformationslike for LESS.
My Controller's App_Start has the RouteConfig. These aren't necessarily critical it's just the way I ended up organizing mine and really depends what aspects you need access to during the startup of those components.
I will say that to save yourself time, in your Views/web.config file, add a namespace entry for your Company.Project.ViewModels namespace so that it's done in one place and you don't have to add it to each view, as this namespace would reside in your Controllers Project.
Your project with the Views will be your startup project. Just make sure in the global.asax your calls to the FilterConfig, RouteConfig and BundleConfig all resolve correctly.
It's fairly easy to do, my recommendation is to try it yourself and split it out the way you want and if you have problems come back and ask about the difficulties rather than looking for a step by step guide.
Bottom line is, yes it's possible and yes it works,
I've got the following project setup
Project A (main)
Business
Data
View (asp.net mvc 3 project)
Project N
Business
Data
View (asp.net mvc 3 project)
How can I call from Project A the View in Project N and from N back to A. Essentially what I'm trying to do is package each Project N to have its own individual MVC as it comes from different sources and plug it in to the main project and then just have it navigate to the correct view.
Can this be done? Or is there a better way to do this?
You could write a custom virtual path provider. Here's a nice blog post which shows an example of such a virtual path provider allowing you to embed Razor views into assemblies as resources and reusing them in multiple applications.
Unfortunately without a custom virtual path provider, you cannot cross reference views between multiple ASP.NET MVC applications. This simply is not allowed by the default provider which looks for views only inside the current application.
I do sugest another approach if possible. if I understood correctly, those projects are somehow ike plugins but they are not standalone applications.Also they now about each others so they are coupled. It's, let's say tricky, but I would use only 1 asp.net mvc project (the web ui). All the UI bits which belong to other projects I'd make them helpers (pretty much widgets). This means, that each project contains only the helpers which will be used to construct a view.
I think it's a bit of an architectural problem if you only want to keep the views in each project just for the sake of hosting them in a different assembly. Going the widgets' way it might seem mkore work, but I think you gain the most control and the separation level you want. The only thing is you don't have full Views defined, but why you would want to have full Views (partials, layouts) in separate places if they will be used in one place only?!
Now, if each project is indeed a plugin, independent of other plugins, then going with compiled views is the best way. But if Project B knows about the view of Project N, then I think the above solution is more suitable. That or the whole app is too over engineered. Separation is good when it doesn't create a whole new jungle to navigate it.
I would like to know how can I do to structure a web application using one folder per feature (Customers, Orders) instead of one folder per artifact type (Controllers, Views); this seems to be a much better way to organize large projects with lots of features, but I can't find any information about it.
I don't think that using Areas would be a solution because using one Area per-feature would require creating lots of nested folders.
I think that what I want to do should be possible by customizing a IViewEngine implementation, but I'm not sure about that.
Has anyone tried to do this?
You can create root Features folder, create one folder for each of your features and Shared folder within it. Then you can add all files (controllers, models, views, scripts) related to a single feature to it's folder. If multiple features use same file you can it to Shared folder. This is how project structure may look like:
- App
- Features
- Orders
- OrdersController.cs
- Create.cshtml
- Create.js
- CreateModel.cs
- Edit.cshtml
- Edit.js
- EditModel.cs
- EditViewModel.cs
...
- Customers
...
- Shared
- _Layout.cshtml
- Error.cshtml
- _ViewStart.cshtml
- Web.config
- FeatureViewLocationRazorViewEngine.cs
...
- Web.config
In order to use Razor with this folder structure you need to create new view engine class inherited from RazorViewEngine, set proper ViewLocationFormats, MasterLocationFormats, PartialViewLocationFormats and add instance of your view engine to ViewEngines.Engines collection. For sample implementation and it's usage check FEATURE FOLDERS IN ASP.NET MVC article by Tim G. Thomas.
If you want to use classes like Scripts in your views you also need to import their namespaces. One way to do this is to copy Web.config file from old Views folder to Features folder. For another options check How do I import a namespace in Razor View Page? question.
For more information check following articles:
FEATURE FOLDERS IN ASP.NET MVC by Tim G. Thomas
FEATURE FOLDERS AND JAVASCRIPT by Tim G. Thomas
Put your controllers on a diet: GETs and queries by Jimmy Bogard
How we do MVC by Jimmy Bogard
You can change the location of where views are stored, if you would like. An example, http://weblogs.asp.net/imranbaloch/archive/2011/06/27/view-engine-with-dynamic-view-location.asp.
ASP.NET MVC is easy to develop with because of the philosophy of convention over configuration. If you really want to change those conventions, you can; however, you will find yourself doing a lot more coding. For example, scaffolding will not work with your configuration.
Why not just create your logical separations inside the artifact folders? So, inside your Models folder have a folder for ViewModels and one for DataModels. Inside the DataModels folder, create folders for the different subsets of models (Customers, Orders, etc.). Just my 2 cents.
is there any particular directory that i should put my code into in an asp.net mvc project
i have some extentions to the HtmlHelper class. Right now i have it sitting in the Content folder. is this correct? is there a better soluiton?
I usually create a separate project (or projects) for my own code, including my data layer, as class libraries. I then reference the libraries in my MVC web site.
you can put code wherever you want, but typically you want things organised. heres how i do it:
2 assemblies
MyProject.Domain
this contains all my domain code; business logic and entities
MyProject.Web
this contains controller code, views and assets like css/images
Your HtmlHelpers belong in the .Web project because they are mvc related (nothing to do with the domain). You probably want a new folder called Helpers or Extentions. Its really up to you, the key point is to decide where something belongs and to namespace it accordingly
I agree with what everyone else said, here's how one of my solutions would look like:
1- MyProject.WebUI
2- MyProject.DomainModel
3- MyProject.Test
4- MyProject.Extensions
This extensions project is new to me (actually since I knew about extension methods). It usually concludes sub-folders describing what the extension methods are used for, for your particular case, the folder name would be HtmlHelpers. I then reference this project (or its output library when using elsewhere). HTH
If you are going to re-use the same HTMLHelper extensions in different ASP.NET MVC projects, I'd suggest putting them in a class library which is completely seperate from your project.
Trying to create a MVC User Control in the Release Candidate and I can't see to make one with a codebehind file. The same is true for MVC View pages.
Creating Views in the Beta would produce codebehinds...am I missing something?
Code behind kind of defeats the purpose of the MVC Framework. Functionality should be kept separate from the view, the MVC team felt that code behind pages went against this ideology and therefore removed them.
Your can create a custom helper method to create your control. Also I'm not sure if MVC has view components (Monorail/Castle) but that could be an option as well.
From ScottGu's Blog post:
*Views without Code-Behind Files
Based on feedback we’ve changed view-templates to not have a code-behind file by default. This change helps reinforce the purpose of views in a MVC application (which are intended to be purely about rendering and to not contain any non-rendering related code), and for most people eliminates unused files in the project.
The RC build now adds C# and VB syntax support for inheriting view templates from base classes that use generics. For example, below we are using this with the Edit.aspx view template – whose “inherits” attribute derives from the ViewPage type:
One nice benefit of not using a code-behind file is that you'll now get immediate intellisense within view template files when you add them to the project. With previous builds you had to do a build/compile immediately after creating a view in order to get code intellisense within it. The RC makes the workflow of adding and immediately editing a view compile-free and much more seamless.
Important: If you are upgrading a ASP.NET MVC project that was created with an earlier build make sure to follow the steps in the release notes – the web.config file under the \Views directory needs to be updated with some settings in order for the above generics based syntax to work.*
I answered this question here:
How to add a Code-behind page to a Partial View
Seems this wasn't particularly tricky, and is quite do-able
This answer worked for a Partial 'ViewUserControl' but the same should apply
Ok.
First: Add a Class file with the convention of .cs (i.e. view.ascx.cs)
Second: Add "using System.Web.Mvc;" to the class
Third: Change the Class to Inherit from "ViewUserControl<>"
Fourth: Add the following to the View's header:
CodeBehind="View.ascx.cs" Inherits="Project.Views.Shared.View"
Fifthly: Copy the files out of the solution and drag back in to reassociate the two together
Note: For this to work with a Normal MVC View you just need to inherit the class from "ViewPage"
The whole idea for ASP.Net-mvc was to get rid of the codebehind files...thats why asp web controls didnt matter that most didn't work.But with the changes of getting rid of the code behind comes with a different programming style..The idea is codebehind files are EVIL:
http://stevesmithblog.com/blog/codebehind-files-in-asp-net-mvc-are-evil/
the whole idea is to make sure people remember they are using asp.Net-mvc and not asp.et web pages. take alook at this link ,it explains it a little better:
http://blog.lozanotek.com/archive/2008/10/20/Visual_Studio_Templates_for_MVC_Views_without_Codebehind_Files.aspx
I think this tutorial is what you are asking.. but not really sure what you want..