views:

1376

answers:

7

Hi,

My question may be obvious but I'd like to build a well-designed web application. As for any administration area, the admin should be able to list/create/delete/modify users, articles, posts, etc...

I'd like to know what is the best way to design the application. Should I create a controller for each one of those items (/Users/Create/id or /Posts/Delete/id), or create all of the action in my Administration Controller (/Administration/CreateUser/id or /Administration/DeletePost/id) ?

A: 

You could use DynamicData for this. It isn't MVC but it can be used together with it and it is really easy to setup and use.

Rune Grimstad
This may be a good idea, but I don't have time to learn how to use DynamicData and make it work with MVC.
Flesym
I used DynamicData in a project recently and both the setup and using it was dead simple. The easiest way would be to create a new project using dynamic data. Then it just works out of the box.
Rune Grimstad
A: 

The answer depends on how much functionality will be in the controllers. Just start of with one controller and if it gets too much split it into a few. The great thing about MVC is where you put things in your controllers doesn't have to have any effect on the URLs. you can very easily map /Users/Create to e.g. UserAdminController class.

Jonathan Parker
+4  A: 

You should write a separate controller for each entity to keep a clean separation of concerns for your controller classes. If you only have one controller, then you will only have one Views directory with dozens of views, and your controller will contain dozens of methods, and that will soon become unmanageable.

womp
+1  A: 

I would just build a new MVC website that handles the administration. You have a more flexible solution as long as you've separated the data and the business logic in different assembly's. You could then publish your website to a subdomain, admin.yoursite.com for example. That way you don't have to mess with your routes and you can keep them in separate views which imho is the most elegant solution. Pro's and Con's would be nice to hear.

I'm working on a project which will need the same administration site but haven't got that far yet so this question interests me a lot.

Peter
A: 

I'm currently using ASP.NET for a large client.

The approach I've adopted is to put the functionality of the action into another class.

Example

I am writing an administration section also. There will be one Administration controller (our admin section is small, if it was larger I would change the routing to allow more controllers, for now we are using the out of the box configuration). If I create an "EditUser" view. I will also create an "EditUserAction" class. All EditUser code will go into the class. I construct the EditUserAction class in the Administration controller class in the Edit User method. This removes all the action specific code out of the Controller class. This way all the action specific code is either in the action method or in the action class. Otherwise, the controller would quickly become overrun with code from various actions. The controller class would balloon to an unmanageable mess in short order.

Class examples

public class Administration: Controller
{
    public ActionResult EditUser(string userId)
    {
      EditUserAction action = new EditUserAction();
    }
}

public class EditUserAction
{
    public void Save(User user)
    { 
     //save code here
    }
}

I hope this explanation is clear. If it's not let me know and I'll clarify.

To answer your question I am doing it the latter(/Administration/CreateUser/id or /Administration/DeletePost/id).

Chuck Conway
I do understand your approach, but it will really be a monstrous mess in my administration controller !I'm building a sort of e-commerce/price comparison web application, and my administration area will certainly grow up quite fast !I think that I will build a new MVC website that'll handle the administration, even if my bosses don't want it that way.
Flesym
A: 

Here is another way of asking my question.

A part of my Master Page:

<% if (!String.Equals(ViewContext.RequestContext.RouteData.GetRequiredString("controller"), "Administration")) { %>
<div>
 <!-- Some Code -->
</div> <% } %>

As you can see, in my master page, I'd like to display some part of the page, depending on the user working on the administration area or not. It works pretty well with only the Administration Controller (/Administration/CreateUser/id)... but it becomes a big mess when I use different controller as User or Article (/User/DeleteUser/id or /Article/Details/id).

I'd prefer to use one controller per entity, but I can't find a way to bond this approach with multiple controllers.

Flesym
If you want to integrate administration into your website like this, I think it would be better to go by a user approach. Just implement everything in the main website, but show the edit/delete/create actions only to people with the correct permissions. It shouldn't depend on the route that is being followed?
Peter
A: 

I suggest to use this solution.

But I changed definition to this:

    public ThemedViewEngine()
    {
        base.MasterLocationFormats = new string[] {
            "~/Views/{1}/{0}.master", 
            "~/Views/Shared/{0}.master",
            "~/Themes/{2}/Views/{1}/{0}.master", 
            "~/Themes/{2}/Views/Shared/{0}.master",
            "~/Themes/Default/Views/{1}/{0}.master", 
            "~/Themes/Default/Views/Shared/{0}.master"
        };
        base.ViewLocationFormats = new string[] { 
            "~/Views/{1}/{0}.aspx", 
            "~/Views/{1}/{0}.ascx", 
            "~/Views/Shared/{0}.aspx", 
            "~/Views/Shared/{0}.ascx",
            "~/Themes/{2}/Views/{1}/{0}.aspx", 
            "~/Themes/{2}/Views/{1}/{0}.ascx", 
            "~/Themes/{2}/Views/Shared/{0}.aspx", 
            "~/Themes/{2}/Views/Shared/{0}.ascx",
            "~/Themes/Default/Views/{1}/{0}.aspx", 
            "~/Themes/Default/Views/{1}/{0}.ascx", 
            "~/Themes/Default/Views/Shared/{0}.aspx", 
            "~/Themes/Default/Views/Shared/{0}.ascx" 
        };
        base.PartialViewLocationFormats = new string[] {
            "~/Views/{1}/{0}.aspx",
            "~/Views/{1}/{0}.ascx",
            "~/Views/Shared/{0}.aspx",
            "~/Views/Shared/{0}.ascx",
            "~/Themes/{2}/Views/{1}/{0}.aspx",
            "~/Themes/{2}/Views/{1}/{0}.ascx",
            "~/Themes/{2}/Views/Shared/{0}.aspx",
            "~/Themes/{2}/Views/Shared/{0}.ascx",
            "~/Themes/Default/Views/{1}/{0}.aspx",
            "~/Themes/Default/Views/{1}/{0}.ascx",
            "~/Themes/Default/Views/Shared/{0}.aspx",
            "~/Themes/Default/Views/Shared/{0}.ascx"
        };
    }

Default theme is default so it is required to exists.

Structure of directory will be:

  • Content
  • Themes
    • Default
      • Content
      • Views
        • Home
        • Blog
        • Whatever should be skinned
    • OtherTheme
      • Content
      • Views
        • Home
        • Blog
        • Whatever should be skinned
  • Views
    • Articles
    • Posts
    • Users
    • Settings
    • Other Administration stuff
dario-g