Is it possible to access MVC Views located in another project?

I want to separate my MVC project into several projects

So first of all, I’ve created two projects Front and Views

The Front project is a web application that contains controllers and models

The Views project is a class library project that will contains only the views

My question is how can I make controllers call views located in the Views project

I have controllers like this one:

public ActionResult Default()
        {
            return this.View();
        }

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

For including controllers you need to change your route registrations to tell them where to look for the controllers:

routes.MapRoute(name: "Default", url: "{controller}/{action}/{id}",
                namespaces: new[] {"[Namespace of the Project that contains your controllers]"},
                defaults: new {controller = "Home", action = "Index", id = UrlParameter.Optional});

For including views, create custom ViewEngine:

public class CustomViewEngine: RazorViewEngine
{
    public CustomViewEngine()
    {
        MasterLocationFormats = new string[]
        {
            "~/bin/Views/{1}/{0}.cshtml",
            "~/bin/Views/{1}/{0}.vbhtml",
            "~/bin/Views/Shared/{0}.cshtml",
            "~/bin/Views/Shared/{0}.vbhtml"

        };
        ViewLocationFormats = new string[]
        {
             "~/bin/Areas/{2}/Views/{1}/{0}.cshtml",
             "~/bin/Areas/{2}/Views/{1}/{0}.vbhtml",
             "~/bin/Areas/{2}/Views/Shared/{0}.cshtml",
             "~/bin/Areas/{2}/Views/Shared/{0}.vbhtml"
        };
        .
        .
        .
    }
}
protected void Application_Start()
{
    ViewEngines.Engines.Add(new CustomViewEngine());

For more information look at the default implementation of RazorViewEngin.

Here some good articles:

A Custom View Engine with Dynamic View Location

Using controllers from an external assembly in ASP.NET Web API

How to call controllers in external assemblies in an ASP.NET MVC application

How do I implement a custom RazorViewEngine to find views in non-standard locations?

Views in separate assemblies in ASP.NET MVC

Method 2

MVC does not compile views into DLL’s, but instead references them as files from the root of your site directory. The location, by convention is ~/Views and a search path is followed. This is more or less hard coded into the default view engines.

Because Views are files, when you break them into a separate project, they won’t exist in your primary web application project. Thus, the view engine can’t find them. When you compile the app, any projects referenced will only copy the DLL’s (and potentially a few other things, like pdb’s, etc.)

Now, there are ways to work around this, but to be honest, they’re usually more trouble than they’re worth. You can look into “Portable Areas” in the mvc contrib project, but these are not well supported and there’s been talk of replacing them with NuGet packaging.

You can also follow @mo.esmp’s advice, and create a custom view engine, but you’ll still need to figure out ways to copy the Views somewhere the site can access them upon build and/or deploy.

My suggestion would be to NOT break out projects in the manner you describe. I don’t see any value in it. If your project becomes so large, I would instead separate your code into areas, and keep all your area code and data together.

What value is there in separating items that are clearly dependent upon each other into separate assemblies who’s only purpose is to collect things based on their purpose? I see some value in separating models into their own project, since models can be used by more than one assembly. Controllers and views, however, are only ever used by the MVC primary site.

Method 3

You can precompile your views – that way they are included in the dll and you can reference them from another project.

How to do it:

  1. Move the views to another project
  2. Install Razor Generator extension in Visual Studio
  3. Change Custom Tool to RazorGenerator for those
    views
  4. Add RazorGenerator.Mvc NuGet package to the view project
  5. Reference view project from your main project

That’s it!

Although you’ll need to do something with your models, either put them together with views or have a third project for them – otherwise you’ll have a circular dependency.

Another drawback is that everyone who will be working with the views will need that Razor Generator extension.

The way this works is basically you make Visual Studio generate .cs files from your views in design time and those are a part of the compiled dll, same as any other piece of code.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x