Adding a controller to NopCommerce - c#

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:

Related

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

ASP.NET MVC Views/Controllers management

I'm working on a pretty big project, which have insane ammount of methods in each controller. Same with Views, one folder contains about 150 .cshtml files, what makes this hard to explore. I wanted to create separate folder for each part of window, but that changes my routing adress from ./Tavern/Shop to /Views/Tavern/Tavern/Shop. Tavern controller have 3000+ lines of code, and even with (Ctrl+F) its hard to find and edit some functionality.
Any ideas how can i improve this without changing many files in solution?
It is hard to help without viewing your code but these should be your guidelines:
Controllers should be as 'skinny' as possible, all the code should be done in your BL layer. (external lib)
Controller should be very specific - i.e. product, contact, home, etc...
The routing is done via the controller, and not the location of the view - you can specify on your return View("~/AnyPath/GoesHere/AndTheRouting/IsTheSame.cshtml") (it will be controller/action) (or however you defined it in the routing.config)
You can consider working with Areas.

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.

Change the Location of the Controller inside the Project structure

I found this Post (How to extend where MVC looks for views) about changing the location of the View.
I was wondering if there's something similar for changing the location of the controller.
I just want to change the location of the class inside project and don't want to affect the url.
For example Instead of placing the Controller into
MyMvcProject\Controllers\
MyController1.cs
MyController2.cs
MyController3.cs
I want to achieve something like
MyMvcProject\MyGroup1\
MyController1.cs
MyController2.cs
MyMvcProject\MyGroup2\
MyController3.cs
and also support Areas:
MyMvcProject\Areas\MyGroup3\
MyController4.cs
Is it possible to achieve this? And if yes, where can I find documentation about it?
You can do what you want, and it doesn't require any special configuration, because ASP.NET MVC does not care about where you put your controllers. First, controllers are located using reflection, so the name of the folder where you put your controllers is irrelevant. Controllers are searched by type name and optionally by namespace (for disambiguation). You can even have controllers in separate projects/assemblies. As long as the controller ends up in an assembly in the bin folder then it's searchable by the framework.
As mentioned above, you'll need to create a controller factory to support your custom resolution. Here's an example:
http://develoq.net/2010/custom-controller-factory-in-asp-net-mvc/
As others have already stated you need to do one of the following:
Derive from IControllerFactory interface and provide an implementation of the CreateController and ReleaseController methods.
Derive from DefaultControllerFactory and override the default behaviours.
Here are some links to get you started:
Custom controller factory in ASP.Net
Inside the ASP.NET MVC Controller factory
Dive deep into MVC - IControllerFactory
Also, if you're willing to spend a bit of money I would also recommend the book Pro ASP.NET MVC 3 Framework as this explains almost every aspect of how the MVC framework can be customised (including an example on how to create a custom controller factory - the source code for which can be freely downloaded from the publishers website).
I think it is impossible to do this. ASP.NET MVC have defined the convention that we have to follow.
Controllers are in Controllers folder, views are in Views{ControllerName}\
I believe you cannot change the convention unless you create your own ControllerFactory.
If you really want to do that, just implement IControllerFactory interface (or try to derive from DefaultControllerFactory).
Then your Application_Start register your controller factory using ControllerBuilder.Current.SetControllerFactory method.
Look at the ControllerFactory documentation and to the MVC source code for details.
What you're asking and what your example shows are two different things; depending on which one you want to achieve, you may or may not need to do any work.
There are two requirements for a class to be a controller in the MVC Framework:
It has to have a class name of Name + "Controller"
It has to have a parameterless public constructor.
Your sample "normal" MVC layout is actually not valid:
MyMvcProject\Controllers\
MyController1.cs
MyController2.cs
MyController3.cs
Those classes wouldn't be found by MVC because they don't have the correct name, regardless of which folder they are in.
If all you want to do is change the namespace/folder names, that "just works", assuming you name them the same as the appropriate route segment(s):
MyMvcProject\MyGroup1\
Page1Controller.cs
Page2Controller.cs
MyMvcProject\MyGroup2\
Page3Controller.cs
MyMvcProject\Areas\Area1\
Area1Page1Controller.cs
This walkthrough (written for MVC 2 but works just as well in MVC3) shows you how to support Areas with the default controller behavior.
If you actually want to name them SomethingController1 or SomethingElseController5, or otherwise change the route -> classname mappings, then you do need to implement a custom ControllerFactory, and inject it into the MVC pipeline.
There are plenty of examples on the web on how to do this, including the one posted earlier.

Mock MVC Site, an Outline for coders to see functionality and to start coding

I have to setup an MVC project to house all the HTML documents. This would be like a hierarchical structure using routing. The pages don’t have to function, just act as placeholders. It’s really just for the group to see all the HTML Pages to get an Idea of functionality. Then we would back fill groups of pages with the functionality by creating the controllers, model etc. How would this be best accomplished? Are there mock frameworks that could accomplish this? So it would be a project just having views, with a control ler that allows navigation between pages, simple to show mostly static HTML pages. The idea is simply for the group to see all the functionality, and to put together a structure to start coding. If possible we would like to see the correct URL based on the route table. What would be a quick solution for this while we work on the back end Object/Domain model?
This is a rather crude but simple solution. Just add the Server.Transfer line to your controller to inject the link to the physical file (I'm assuming the HTML documents exist already):
public ActionResult About()
{
//TODO: remove mock up redirect
Server.Transfer("~/MockUps/AboutUsMockUp.htm");
return View();
}
If you already have the HTML I would just go ahead and implement the views whilst you create the controllers? It may seem like a little extra work up front but by the time you work back through the above suggestion to re-implement the proper views at a later stage that could equate to more time spent!?

Categories

Resources