Implementing modular asp.net mvc project layout - c#

Here by modularity I do mean the feature based layout like this one:
(I've read about areas. And I'm not asking about areas)
For example, using NancyFx this thing is achieved easilly. As for ASP.NET MVC I've tried to extend the standard RazorViewEngine by replacing its view search paths. As the result views were found but the static content they referenced couldn't be loaded (404 error with message saying that there's no corresponding controller to match a request to /assets/css/dashboard.css)
I have seen many posts where people implemented custom view engines, redefined the CreateView, FindView, GetGeneralNameFrom methods and so on. But I don't get the whole thing on the ASP.NET MVC conventions.
What conventions should be changed in order to let controllers reside with its feature-related code (services, views, models) in the same feature-folder?
I'm asking about the internals I've got to change/replace/extend.

You must not place your view with your code files. In MVC you should have separate folders: Models, Controllers, Views. The MVC engine searches views in Views folder.
In your case in your Views folder you need to have subfolders Authentication and Dashboard. In each subfolder you place your index pages and other pages related only to this part of application. For example, if you have separate view edit for dashboard editing you place it in Views - Dashboard
The same is for controllers' classes. You have Controllers folder and subfolders Dashboard, Authentication. The same rule is for models' classes
For all .js files you should have Scripts folder, for all css rules - Content folder
And you do not need your custom ViewEngine for rendering pages. Its only needed if you have some non-generic templating or some business requirements

Related

MVC in a Core Library

I built this project and it contained a simple MVC type structure to help with debugging information. Now the company wants to use it in other applications like a Library
The best way, I can describe it is
My Project Debugger Is a single controller with multiple end-points that render views (pretty basic), written in C#.
What I want is when another project wants to include my debugging, they would:
Add Debugger as a reference using NuGet.
Then in Start.cs the developer would use IApplicationBuilder.UseDebugger(IConfiguration, OtherInformation) or IServiceCollection.UseDebugger(IConfiguration, OtherInformation) and Debugger extension would do the rest like registering routes, building what it needs for dependency injection.
What I cannot figure out is what project type to use, I built it using .NET Core Web Application 3.1, but I do not think it is that. I also tried a .Net Standard class Library but I could not get a reference to controller to render views.
So to summarize, I want to convert part of my project to a library to allow for distribution to other applications.
A link to an example project would be helpful as well.
It sounds like you want a Razor Class Library.
Razor views, pages, controllers, page models, Razor components, View components, and data models can be built into a Razor class library (RCL). The RCL can be packaged and reused. Applications can include the RCL and override the views and pages it contains. When a view, partial view, or Razor Page is found in both the web app and the RCL, the Razor markup (.cshtml file) in the web app takes precedence.
Edit: I just realised I answered a question about setting up a Razor Class Library last month, so that will give you a starting point, too.

How to organise Views into folders in Asp.net visual studio?

I have been forking on a project for a while now and I ended up having a lot of view for different models. I was wandering whether it is possible to organise these views into sub folders. So just to be clear I want to do the following:
Controllers:
MyControllers(Folder)->
MyFirstController.cs
MYSubcontroller(Folder)->
MySubController.cs
Views:
MyFirst(Folder)->
Index.cshtml
MYSub(Folder)->
Index.cshtml
You are allowed to put views and controllers wherever you want. You can easily customize view paths on App_Start event. See tha answer in this topic: Can I specify a custom location to "search for views" in ASP.NET MVC?
I would though recommend using the standard project structure and paths. It would makes life easier for other developers that work with your code in the future eventually.
Most basic option would be for your controller routes to specify a view explicitly when returning:
return View("PATH-TO-YOUR-VIEW");
But I'm not a fan of this approach as you lose the nice built in MVC conventions.
By default, the Razor View Engine will use the following conventions when locating views:
~/Views/{1}/{0}.cshtml
~/Views/{1}/{0}.vbhtml
~/Views/Shared/{0}.cshtml
~/Views/Shared/{0}.vbhtml
The view name
The controller name
With this in mind, if you have a controller named MySubController with the default Index action, you would normally have a view file:
~/Views/MySub/Index.cshtml

Adding a controller to NopCommerce

I am writing my own Payment method for NopCommerce (for Datacash to be precise, if somebody can point me towards a Datacash implementation of IPaymentMethod for NopCommerce that would also answer my question).
The documentation provided by NopCommerce for doing this is great, and that is what I am using as my reference, but I am very new to MVC, and the first step is to create a new controller.
I understand that, in regards to MVC, you have models, views and controllers. The model is to do with how the data for your website is modelled, the view is what you see (your HTML etc) and the controller is the programming logic behind what you see.
In any MVC Hello World Application I have done so far, you usually have a folder for your models, one for your views and one for your controllers, as shown below:
However, NopCommerce looks like this:
So my question is in which folder do I put the controller I am about to create (or does it even matter)?
Thanks
One observation: it looks like you didn't download the source version of nopCommerce, which does indeed have "Controllers" folders:
On the nopCommerce downloads page (http://www.nopcommerce.com/downloads.aspx), look for the version "with source code", if you're looking to do customization of any sort.
You don't have to but it is best/wise to.
The convention like you said is to have a View, Model and Controller.
So create a Controller folder, and you can either put your Controller class directly in the folder or do the better thing and create a NOPCommerceController folder so it looks like:
Controller/NOPCommerceController/SomeController.cs
Nice and clean.
You should create your controllers and models inside your plugin project:

Can MVC Views access all projects even though they aren't referenced by the project where the views are?

Ok, so I'm a bit confused as to what is going on with the following data.
We have the following Structure in our application:
Portal.Web - An MVC 3 Web App which basically contains all the
views, scripts, css and HTML helper extension methods
Portal.Core - A Class Library which is basically our Business Objects, we have all of our models contained within this project.
Portal.Data - Another Class Library which contains our NHibernate config and our DTO classes.
Here's our usage: In the controller we call the model located in Portal.Core, which populates by calling Portal.Data, so basically Web can never see data.
Here's the catch: In the controller, say for example I try and instantiate a new DTO object called Client like so:
var client = new Client();
It won't work, which is expected it has no idea what Client is and even specifying a using won't cut it. That's fine.
BUT if I try and do that exact same line in the View, Resharper adds the using to the view and then no complaints, the project runs and we can use DTO classes in our views.
So the question is, why is this? I'm trying to stop our juniors from using DTO classes in Views, so I've purposely removed the reference to the Data project in Web, but they can still use the classes. Can someone shed some light?
I ran the same test with ASPX and Razor views. Referencing Client in ASPX views fails however in Razor views they work. The views are compiled on the fly when you request the application, so I had a look at some folders in "C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\portal.web" and from cmdline files references to the assembly is explicitly added when the view is compiled.
It seems the process that compiles razor views adds references to all the assemblies in the bin folder. However, looking at the source of ASP.NET MVC, I cannot confirm this.
So, the only conclusion I can come to is that it is a side effect of using the Razor View Engine.
That said, you may want to scan the web.config to see if it was included using the assemblies element.

How to extend where MVC looks for views

I an application that has a concept of discrete modules. These modules will live in Modules folder. Each module will have a folder under this Modules folder. These module folders will then have a Controllers and Views folder under them, very similar to how Areas work.
I would like to extend/change the search locations that are searched so that when my module controllers return a view the new locations will be searched.
I am thinking this will need to involve a custom ViewEngine, but I am uncertain of the specifics. Is there a specific viewengine I can extend, or do I need to write a new one from scratch.
Is writing a custom view engine the right way to go, or is there a better route?
I am thinking this will need to involve a custom ViewEngine
Correct thinking.
Instead of extending a specific view engine you can implement a view engine wrapper, that way your custom logic for locating views can work with multiple view engines. That's how MvcCodeRouting works, by temporarily replacing the controller value in controllerContext.RouteData.Values, so when a location format is used (such as ~/Views/{1}/{0}.aspx) you can inject into those placeholders your custom location.

Categories

Resources