I am adding MVC support to a legacy ASP.NET Website project. I have added a separate class library for the Controllers and the Views are in the legacy app. It works great so far, but I'd like to take advantage of Areas. Since Areas encapsulate Controllers, Views and Models, if i add a new class project to host the Areas then would it work with the Views in this project?
Also, Areas need a web.config file and I assume I cant add a web.config to a class library Areas project.
Is this even possible?
I don't think the View files can be placed outside of the MVC3 project (it has to know where to find the files).
You can, however, specify a namespace for your Area routes that specifies where to search for your Controllers (so your controllers can remain in a separate project).
context.MapRoute("routename",
"{controller}/{action}",
new { controller="Home",action="Index"},
null,
new[] {"ControllerProject.NamespaceTo.Controllers"}
);
You will need to be sure you reference the proper ProjectTypeGuids in your project file.
http://www.kevinrohrbaugh.com/blog/2009/7/17/demystifying-the-aspnet-mvc-project-type.html
Be sure you have added the proper references for MVC as well. When all is configured, visual studios should allow you to right click the project and add areas with the supporting structure.
Related
Using the base Exrin template, I am unable to use custom controls.
As it stands now, the Droid/iOS projects reference the App/Bootstrapper project, so that seems like the correct place to put them, but when creating a new page or BaseView, I am not able to access the custom control's namespace because the View project does not reference the App/Bootstrapper project.
The Tesla sample app does not have this problem in its current implementation since there is no separation of the App/Bootstrapper and the View projects.
(1) Should a reference to the App/Bootstrapper be placed in the View project or (2) should a reference to the View project be placed in the Android/iOS/etc projects? Or is there a better solution than either of these two?
Edit:
(1) does not work because a reference to the App project from the View would create a circular dependency.
(2) should work (I think), but I'm having trouble getting the Application.Droid project to access the Application.View project namespace because when I add using Application.View;, the namespace isn't found in the Application namespace. Visual Studio attempts to fill in other Application namespaces (.Container, .Logic, .Droid, .Proxy) when I type in using Application.
The native project can have a reference to the View. It already does in a way, because it references the App library, which then references the View. Hence you aren't really adding any further dependencies by doing this, just allowing access further up the chain.
If you are having trouble the namespace, I suggest you start out with
global::Application.
That way it starts from the top, if its getting mixed up with project namespaces.
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();
}
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
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.
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:
Move the views to another project
Install Razor Generator extension in Visual Studio
Change Custom Tool to RazorGenerator for those
views
Add RazorGenerator.Mvc NuGet package to the view project
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.
I converted a web site project to a web application using this guide
http://msdn.microsoft.com/en-us/library/aa983476%28v=vs.100%29.aspx
In the guide it says that I have to add namespaces to my classes but I did not do that. The classes I have in the Old_App_Code directory are not placed into namespaces and the application runs just fine (tested on different machines). Is it because there is something special about Old_App_Code or am I missing something? Thanks.
You are misinterpreting what the guide is saying, it is NOT saying that you need to add namespaces to get the code to compile, but rather that the conversion process does not add the namespaces into the code files by using the folder/file naming constructs.
The guide is further underscoring the fact that when you add new items (i.e. classes) in a web application versus a web site; the namespace is automatically added to the code file, based upon the folder structure and file name of the of new class.
In my asp.net project currently i have business logic and and data access code in two sub folders(BLL,DAL) which are itself located web site project's app_code folder. I need to segregate them to two separate projects(one project for business layer and one project for Data access code).
How can I maintain connection strings necessary to Data access project which are currently in web.config file?(i.e if I choose Class library template for creating DAL and BLL projects)
How can I maintain various other web.config key values that are currently used in BLL, DAL code files?
How can I deploy compiled project? (ie Web site project I am currently deploying bin folder to Staging> production but this way where should i put DAL.dll and BLL.dll and relevant config files)
1 and 2) Add a 'using System.Configuration' and just reference them. Since their referenced in the project, asp.net will pick it up.
For example:
using System.Configuration;
namespace DataLayer
{
public class BaseDataAccess
{
public static string ConnectionString_Logging
{
get
{
return ConfigurationManager.ConnectionStrings["ConnectionString_Logging_Legacy"].ToString();
}
}
}
}
3) If properly referenced, upon compile, your BLL and DAL dlls will be in your bin folder of the main/ui project. If using web.config, your good to go.
Fundamentally, you should be wrapping those configuration bits up in objects along the way. But in any case, you can move them to a different class project without worry here -- it will pick up the configuration settings from whatever project it is hosted by, so you don't need to somehow provide the configuration to your library.
Your existing code should work, as the settings are read from the Config file of the running process, in this case your Web.Config, however i suggest you use custom configuration settings, these would be read from your Web.Config file, a typical implementation could look something like :
<YourCompany>
<YourCompany.ProjectName>
<Data ConnectionName="NameOfConnectionToUse" SomethingElse="XZY" />
<Business SomeValue="12345" />
</YourCompany.ProjectName>
</YourCompany>
Without getting into ideal settings/custom config etc, as asked - during runtime, your class libraries will get the configuration from the web.config if referenced as such from within these layers with no change. System.Configuration.AppSettings/ConnectionStrings will still work.
I'm trying to find a way to generate an enums class dynamically from lookup tables in a database and still have the convenience of a normal class (i.e. intellisense).
I've spent the past few hours trying to figure out how to get a custom BuildProvider to work inside an ASP.NET Web Application. The code works perfectly in a Web Site. I then found an article on MSDN that says
Adding a customized BuildProvider class to the Web.config file works in an ASP.NET Web site but does not work in an ASP.NET Web application project. In a Web application project, the code that is generated by the BuildProvider class cannot be included in the application. For more information, see Compiling Web Application Projects.
Does anyone know if it is possible to generate code dynamically and still be able to 'use' it at design time? Using a web site is not an option. I need to use a web project.
Thanks!!
what is the point of an enum class for a dynamic lookup table? your code references will always be static anyway...
if the initial population of the lookup table is static, make an enum for that and don't reference any other values in the code
If MSDN is saying you can't do it, I'd take another approach. Maybe write a small Console application that writes your Enums.cs file and run it through the "Pre-build event command line". Then, every time you build the web application, the Enums class gets recreated and should be accessible through Intellisense.
Haven't done this myself. Hope it helps.