I have a controller called AuctionsController. In it I have Actions called Index() and AuctionCategoryListing():
//Used for displaying all auctions.
public ActionResult Index()
{
AuctionRepository auctionRepo = new AuctionRepository();
var auctions = auctionRepo.FindAllAuctions();
return View(auctions);
}
//Used for displaying auctions for a single category.
public ActionResult AuctionCategoryListing(string categoryName)
{
AuctionRepository auctionRepo = new AuctionRepository();
var auctions = auctionRepo.FindAllAuctions()
.Where(c => c.Subcategory.Category.Name == categoryName);
return View("Index", auctions);
}
As you can tell, they both invoke the same View (is this action called 'to invoke a view'. What is it's proper name?).
#model IEnumerable<Cumavi.Models.Auction>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th></th>
<th>
IDSubcategory
</th>
<th>
IDCity
</th>
<th>
IDPerson
</th>
<th>
Title
</th>
<th>
TextBody
</th>
<th>
ContactNumber
</th>
<th>
AskingPrice
</th>
<th>
AddressDirection
</th>
<th>
LatestUpdateDate
</th>
<th>
VisitCount
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
#Html.ActionLink("Details", "Details", new { id=item.ID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
<td>
#item.IDSubcategory
</td>
<td>
#item.IDCity
</td>
<td>
#item.IDPerson
</td>
<td>
#item.Title
</td>
<td>
#item.TextBody
</td>
<td>
#item.ContactNumber
</td>
<td>
#String.Format("{0:F}", item.AskingPrice)
</td>
<td>
#item.AddressDirection
</td>
<td>
#String.Format("{0:g}", item.LatestUpdateDate)
</td>
<td>
#item.VisitCount
</td>
</tr>
}
</table>
They both inherit from the same Model.
My question is, am I doing things the right appropriate way? Or is this just a hack I managed to scrape together. Help me before I learn a bad habit.
I'd modify this to:
public ActionResult Index(string categoryName)
{
AuctionRepository auctionRepo = new AuctionRepository();
var auctions=auctionRepo.FindAllAuctions();
if (!string.IsNullOrEmpty(categoryName))
{
auctions = auctions.Where(c => c.Subcategory.Category.Name == categoryName);
}
return View(auctions);
}
Your route might then look like:
context.MapRoute(
"auction_defalt",
"Auction/{categoryName}",
new { controller="Auction", action = "Index", categoryName = UrlParameter.Optional }
Since the actions are so similar, I don't see a reason to separate them.
Like any framework ASP.NET MVC gives you plenty of opportunities to shoot yourself in the foot. Without forethought the reuse of controller actions, view models, and views can quickly become a maintenance nightmare. Not to mention that without similar consideration your routes will become hard to tie together.
Following the tenets of convention over configuration you could solve your problem by using separate actions but reusing a view partial. To me the index action of the AuctionsController should be responsible for listing all Auctions in the system. I wouldn't call my category action AuctionCategoryListing, but would instead call it simply Category. Through convention this has the nice effect of laying out the routes as:
site.com/auctions/ for the index
site.com/auctions/category/CATEGORYNAME for the category.
The route is easily understandable by the user and easy for you to understand explicitly what each does. (To this point Omar provides a good suggestion in his answer to let your repository handle pagination, filtering etc.)
As far as what each action should return you have several options. My preference would be to return separate views each containing a reference to a common partial. This gives you flexibility to create different views surrounding the partial but provides reuse for the piece that is common.
Further reading that might be of help:
One ViewModel per View
ASP.NET MVC terminology is tripping me up - why 'ViewModel'?
when should i use partial views in asp.net mvc?
You have to do branching somewhere, so it's probably more of a preference question.
The way I would handle it is to have a single method, and have it take in the category name as the parameter. Since strings are nullable, if one is not specified it will be null. My one action method would probably look something like:
public ActionResult Index(string categoryName)
{
AuctionRepository auctionRepo = new AuctionRepository();
var auctions = auctionRepo.FindAllAuctions();
if(String.IsNullOrEmpty(categoryName) == false)
auctions = auctions.Where(c => c.Subcategory.Category.Name == categoryName);
return View(auctions);
}
I would prefer the repo to do things like filtering and pagination for the sake of performance and DRY concept
public ActionResult Index(string categoryName)
{
AuctionRepository auctionRepo = new AuctionRepository();
//Let the Repo Handle things like filtering and pagination, avoiding performance issues
var auctions = auctionRepo.FindAllAuctions(categoryName);
return View(auctions);
}
DAL should be responsible for this tasks.
It's a feature of MVC that the view and controller are independent. You could equally use shared or partial views for the same thing, if anything I'd say it's a good thing because you're writing re-usable code and making use of it.
Related
I have a model, which can represent 3 categories. I want in my view, make 3 different tables for each category with relevant fields. I think for this I need to use partial view with viewmodel for each category.
So my main model is "Ad", which have 3 sub viewmodels (Realty, Auto and Service).
Here the example how I implement Realty action on my home controller:
public ActionResult Realty()
{
var ads = db.Ads.Include(a => a.Realty);
var vm = new List<RealtyViewModel>();
foreach (var ad in ads)
{
vm.Add(new RealtyViewModel
{
Title = ad.Title,
Descirpiton = ad.Descirpiton,
Type = ad.Realty.Type,
NumberOfRooms = ad.Realty.NumberOfRooms
});
}
return PartialView(vm);
}
Then my partial view, looks like this:
#model IEnumerable<OGAS.Areas.Category.ViewModels.RealtyViewModel>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Title)
</th>
<th>
#Html.DisplayNameFor(model => model.Type)
</th>
<th>
#Html.DisplayNameFor(model => model.Descirpiton)
</th>
<th>
#Html.DisplayNameFor(model => model.NumberOfRooms)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.Type)
</td>
<td>
#Html.DisplayFor(modelItem => item.Descirpiton)
</td>
<td>
#Html.DisplayFor(modelItem => item.NumberOfRooms)
</td>
</tr>
}
</table>
Then in my Index page (without using any models), I call partial view like this:
#{Html.RenderPartial("Realty");}
But then I'm getting following error:
An exception of type 'System.NullReferenceException' occurred in App_Web_gdyh352c.dll but was not handled in user code
Could you please advise if this approach is good (calling 3 vms), if yes how to implement this?
Thanks.
Try to replace #{Html.RenderPartial("Realty");} and use #Html.Action("Realty") in this case, as you need to call back to the controller action, in order to create the model for the partial view.
See MVC Html.Partial or Html.Action for more information.
Use this, for .net core and mvc. #Html.Action has been removed from .net core
#await Html.PartialAsync("_YourPartialViewName", YourModel)
I am using PagedList.Mvc and I have added a nice way to navigate across various pages in a mvc web application. However, when I click on an "edit" or "details" tab and save changes I am sent back to the 1st page. I want to remain on the same page where the changes were made.
Here is the code I have in the controller:
// GET: Item
public ActionResult Index(int? page)
{
var items = db.Items.Include(i => i.PurchaseOrder);
return View(items.ToList().ToPagedList(page ?? 1, 3));
}
Here is the code I have in the view:
#using PagedList;
#using PagedList.Mvc;
#model IPagedList<PurchaseOrders.Models.Item>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.First().ItemDescription)
</th>
<th>
#Html.DisplayNameFor(model => model.First().Quantity)
</th>
<th>
#Html.DisplayNameFor(model => model.First().Price)
</th>
<th>
#Html.DisplayNameFor(model => model.First().DueDate)
</th>
<th>
#Html.DisplayNameFor(model => model.First().DateReceived)
</th>
<th>
#Html.DisplayNameFor(model => model.First().Comments)
</th>
<th>
#Html.DisplayNameFor(model => model.First().PurchaseOrder.PurchaseRequest_)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.ItemDescription)
</td>
<td>
#Html.DisplayFor(modelItem => item.Quantity)
</td>
<td>
#Html.DisplayFor(modelItem => item.Price)
</td>
<td>
#Html.DisplayFor(modelItem => item.DueDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.DateReceived)
</td>
<td>
#Html.DisplayFor(modelItem => item.Comments)
</td>
<td>
#Html.DisplayFor(modelItem => item.PurchaseOrder.PurchaseRequest_)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ItemId }) |
#Html.ActionLink("Details", "Details", new { id=item.ItemId }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ItemId })
</td>
</tr>
}
</table>
#Html.PagedListPager(Model, page => Url.Action("Index", new { page }))
Please help!
You could pass an additional 'page` parameter to your edit method, for example
In your Index method, add
ViewBag.CurrentPage = page; // or use a view model property
Then your link would be
#Html.ActionLink("Edit", "Edit", new { id=item.ItemId, page = ViewBag.CurrentPage})
Then your edit method
[HttpGet]
public ActionResult Edit(int ID, int page)
{
ViewBag.CurrentPage = page; // pass current page to edit view
And your edit view
#using (Html.BeginForm(new { page = ViewBag.CurrentPage })) {
And in you post method
[HttpGet]
public ActionResult Edit(EditModel model, int page)
{
.... // Save
return RedirectToAction("Index", new { page = page });
In this case the page is stored in the ViewBag which makes it ephemeral (the ViewBag is only available for the current request).
In the controller, you're telling it if you get null use 1 as your current page. so null is always retuned and you get the 1st page everytime.
You need to provide the current page Number to your views that you navigate to (Edit/Create) and then provide it back to the original page when you're done.
You can use the TempData,that works well on HTTP redirects and lives longer than viewbag or viewData.
You can also move it arround with your models when calling actions and then give it back to the index action that needs a page number.
You can use sessions too. BTW, TempData is using session behind the scenes.
UPDATED:
Code to add in your index action:
var page = TempData["page"];
Code to add in the Create or Edit Submit action
//Get the page number
var page = TempData["page"];
//Set it back to Tempdata (because Tempdata is only for redirects) otherwise it will be lost
TempData["page"]=page;
add the value of the parameter to TempData["page"] when calling back the index action again
You can also access it from Index action directly since we repopulated it:
var page = TempData["page"];
return View(items.ToList().ToPagedList(page ?? 1, 3));
I also had this problem.
I tried to put it in the URL at first but it seems a bit weird to have ?page=2 in our URL.
So I replaced it with using TempData
What you need to do is this:
Store the page in TempData when you are in your Index() action method;
public const string PAGE_QUERY_STRING_KEY = "page";
public ActionResult Index(int page = 1)
{
TempData[PAGE_QUERY_STRING_KEY] = page;
...
}
Then use TempData.Peek(), instead of TempData[], everywhere else (to retain the value of your page between requests which are related to your current Index page) --- in your Edit, Create, Details, etc. action methods:
public ActionResult Edit(...)
{
...
return RedirectToAction(nameof(Index), new { page = TempData.Peek(PAGE_QUERY_STRING_KEY) });
// do not do this because this will remove the temp data
// return RedirectToAction(nameof(Index), new { page = TempData[PAGE_QUERY_STRING_KEY])
}
... and in your views:
<!--(Edit.cshtml)-->
...
<p>
#Html.ActionLink("Back to List", "Index",
new { page = TempData.Peek(FLP.Web.Controllers.UsersAdminController.PAGE_QUERY_STRING_KEY) })
</p>
How to do pagination in C# MVC?
I'm trying to do something like this,
I want retrieve 1000 records from database and keep it in server side then i want to send 10 records per each page to view when user requesting the searched page.
I have gone through some examples but i couldn't get better solution, I prefer that the way i suggested or something better solution for this. (I'm using jquery as well and not using Razor)
example which I gone through
Paginated search results with LINQ to SQL
Thanks in advance
Paging in ASP.NET MVC is a solved problem by some libraries; you can find them at Nuget.org by
http://www.nuget.org/packages?q=paging.
I want retrieve 1000 records from database and keep it in server side then i want to send 10 records per each page to view when user requesting the searched page.
Retrieving 1000 records and keep them in your application wouldn't be ideal. It would be better to retrieve 10 records in every request; as you have mentioned in your question, the solution that use Skip and Take in a linq query is perfect. However, there is no problem to page cached data.
Try This
One of the easiest method
Controller
using PagedList;
public ActionResult Index(int ? pagePos)
{
//return View(db.Items.ToList());// Change this as following
int pageNumber = (pagePos ?? 1);
return View(db.Items.ToList().ToPagedList(pageNumber, 30)); //30 is the size of records in a single page
}
Index.cshtml
#*#model IEnumerable<ProjectDB.Models.Item>*#
#*Change These Also as following*#
#model PagedList.IPagedList<ProjectDB.Models.Item>
#using PagedList.Mvc
<table class="table">
<tr>
<th>
Name
</th>
<th>
ID
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.ID)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
#Html.ActionLink("Details", "Details", new { id=item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
#*Pagination Code Starts*#
<div class="pageCount">
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
</div>
#Html.PagedListPager(Model, pagePos => Url.Action("Index", new { pagePos }))
I have a list of information sources in a database that I need to pass to a view in MVC. I need an end user to be able to tick the sources of information that apply to their course.
I am able to successfully pass the view a list of information sources alongside check boxes using the following code.
public ViewResult CreateUpdateInfoSource(int ProgrammeId)
{
List<ProgInfoSourceModel> viewmodel = new List<ProgInfoSourceModel>();
List<ProgInfoSourceDTO> myProgInfoDTOList = progInfoSourceService.AllInfoSources();
if (myProgInfoDTOList.Count != 0)
{
foreach (var x in myProgInfoDTOList)
{
ProgInfoSourceModel insert = new ProgInfoSourceModel();
insert.Selected = false;
insert.ProgrammeId = ProgrammeId;
insert.InfoSourceId = x.InfoSourceId;
insert.InfoSource = x.InfoSource;
insert.InfoReference = x.InfoReference;
insert.Rank = x.Rank;
viewmodel.Add(insert);
}
}
return View(viewmodel);
}
I am able to unpack this in the view just fine, however I am having real difficulty passing a the list back to my controller. I need to be able to loop through the list in my controller and see which ones do or don't apply so I can update the database.
My model looks like this:
namespace ProgrammeSpec.MVC.Models
{
public class ProgInfoSourceModel
{
[DisplayName("Selected")]
public bool Selected { get; set; }
[DisplayName("Programme Id")]
public int ProgrammeId { get; set; }
[DisplayName("Info Source Id")]
public int InfoSourceId { get; set; }
[DisplayName("Info Source")]
public String InfoSource { get; set; }
[DisplayName("Reference")]
public String InfoReference { get; set; }
[DisplayName("Rank")]
public int? Rank { get; set; }
}
}
My View looks like this:
<html>
<head>
<title>CreateUpdateInfoSource</title>
</head>
<body>
#using (Html.BeginForm())
{
<table>
<tr>
<th>
Selected
</th>
<th>
ProgrammeId
</th>
<th>
InfoSourceId
</th>
<th>
InfoSource
</th>
<th>
InfoReference
</th>
<th>
Rank
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.CheckBoxFor(modelItem => item.Selected)
</td>
<td>
#Html.DisplayFor(modelItem => item.ProgrammeId)
</td>
<td>
#Html.DisplayFor(modelItem => item.InfoSourceId)
</td>
<td>
#Html.DisplayFor(modelItem => item.InfoSource)
</td>
<td>
#Html.DisplayFor(modelItem => item.InfoReference)
</td>
<td>
#Html.DisplayFor(modelItem => item.Rank)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</table>
<input type="submit" value="Update" />
}
</body>
</html>
and the controller that the view gets passed to looks like this: (snippet)
[HttpPost]
public ActionResult CreateUpdateInfoSource(List<ProgInfoSourceModel> viewmodel)
{
if (ModelState.IsValid)
{
try
{
The problem is the viewmodel is null. I understand this is probably because I've unpacked the list in the view so it is no longer a list but how can I access the values of the check boxes then?
The added complication is that the number of info sources will vary so I can't use a static form or list and give each one an Id...
This must be a fairly common problem with a simple solution, but I'm an MVC novice and I don't know how to get round this.
Try using an editor template (Here's another SO that answers that question How to create custom editor/display templates in ASP.NET MVC 3?), for your ProgInfoSourceModel and then simply use Html.EditorFor(m => m.Model) on the View.
When you use the foreach loop, each checkbox is getting the same input name - and so is not actually submitting the correct data back.
If you go the editor template route, and making MVC do the hard work of iterating through the IEnumerable - it will create inputs with names like 'item[0].Selected' - which the model binder then correctly deserialized back into a list.
Phil Haack also blogged a fantastic walkthrough of exactly this scenario way back in 2008: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Consider this Scenario:
I want to build an MVC application for Northwind Database. I want to have a view that list some orders and I want to create links for CustomerID and EmployeeID and a details link for [OrderDetails] so that when a user clicks any of these links related data will appear in the same page.
My problem is how to decouple this data that is interrelated into views and controllers that show related data in a page, and controllers responsible for individual parts of the information.
Also, how do I configure routing for this sample?
<table width="500px">
<tr>
<th></th>
<th>
OrderID
</th>
<th>
CustomerID
</th>
<th>
EmployeeID
</th>
<th>
OrderDate
</th>
<th>
RequiredDate
</th>
<th>
ShippedDate
</th>
<th>
ShipVia
</th>
<th>
OrderDetails
</th>
</tr>
<% foreach (var item in Model) { %>
<tr>
<td>
<%: Html.ActionLink("Edit", "Edit", new { id=item.OrderID }) %> |
<%: Html.ActionLink("Details", "Details", new { id=item.OrderID })%> |
<%: Html.ActionLink("Delete", "Delete", new { id=item.OrderID })%>
</td>
<td>
<%: item.OrderID %>
</td>
<td>
<%: item.CustomerID %>
</td>
<td>
<%: item.EmployeeID %>
</td>
<td>
<%: String.Format("{0:g}", item.OrderDate) %>
</td>
<td>
<%: String.Format("{0:g}", item.RequiredDate) %>
</td>
<td>
<%: String.Format("{0:g}", item.ShippedDate) %>
</td>
<td>
<%: item.ShipVia %>
</td>
<td>
<%: Html.ActionLink("OrderDetails", "GetOrderDetails", new { id = item.OrderID })%>
</td>
</tr>
<% } %>
</table>
<p>
<%: Html.ActionLink("Create New", "Create") %>
</p>
<div>
<p>
<% Html.RenderPartial("GetOrderDetails"); %>
</p>
<%--<uc1:GetOrderDetails ID="GetOrderDetails1" runat="server" />--%>
</div>
and Order Details partial view:
<table>
<tr>
<th></th>
<th>
OrderID
</th>
<th>
ProductID
</th>
<th>
UnitPrice
</th>
<th>
Quantity
</th>
<th>
Discount
</th>
</tr>
<% foreach (var item in Model) { %>
<tr>
<td>
<%: Html.ActionLink("Edit", "Edit", new { id=item.OrderID }) %> |
<%: Html.ActionLink("Details", "Details", new { id=item.OrderID })%> |
<%: Html.ActionLink("Delete", "Delete", new { id=item.OrderID })%>
</td>
<td>
<%: item.OrderID %>
</td>
<td>
<%: item.ProductID %>
</td>
<td>
<%: String.Format("{0:F}", item.UnitPrice) %>
</td>
<td>
<%: item.Quantity %>
</td>
<td>
<%: item.Discount %>
</td>
</tr>
<% } %>
</table>
<p>
<%: Html.ActionLink("Create New", "Create") %>
</p>
global.asax:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default2", // Route name
"{controller}/{action}/{OrderId}/{CustomerID}", // URL with parameters
new { controller = "NorthwindOrders", action = "Index", OrderId = UrlParameter.Optional, CustomerID = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
Given this structure; how I can display order details under the order list when any of the OrderDetails links are clicked?
And, why is the URL displayed like this when I click on OrderDetails links:
http://localhost:49444/NorthwindOrders/GetOrderDetails?id=10250
I want the URL to display this way:
http://localhost:49444/NorthwindOrders/GetOrderDetails/10250
For your routing question:
if you set up a route like so:
routes.MapRoute(
"orderdetails", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "NorthwindOrders", action = "GetOrderDetails", id = UrlParameter.Optional, CustomerID = UrlParameter.Optional } // Parameter defaults
);
It will build the URL in the fashion you're wanting.
(Alternatively, you can rename the parameter to your GetOrderDetails action to string OrderId and it will find the route that formats the URL the way you want it.)
As far as your main question:
How do I 'dynamically' load content on the page based on clicks to links?
There are two ways to approach this:
Post back pages.
AJAX / Dynamic loading of data and elements in the HTML on your page.
In the post-back scenario:
In this scenario your links would all go to actions that build a model that includes the orderlist from your main page, and for the details of the specific order you clicked you'd populate your model with specifics for that order. Then your ActionResult return is the same view (or one that looks the same at least), and your view would use the PartialView Html helper to render the details.
OrderViewModel:
public class OrderViewModel
{
public IList<Order> Orders {get;set;}
public OrderDetail Details {get;set;}
}
OrderView.aspx:
<%# Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage<OrderViewModel>" %>
<%:Html.DisplayFor(m=>m.Orders)%> <%-- Displays the Table above listing orders --%>
<%:Html.DisplayFor(m=>m.Details)%> <%-- Displays your custom view of the details --%>
OrderController:
...
public ActionResult List()
{
var model = new OrderViewModel { Orders = GetAllOrders(), Details = null };
return View("OrderView", model);
}
public ActionResult GetOrderDetails(string OrderId)
{
var model = new OrderViewModel { Orders = GetAllOrders(), Details = GetOrder(OrderId) };
return View("OrderView", model);
}
...
In the Ajax scenario:
The Ajax scenario is essentially the same except that you hide the server round-trip in an ajax call, and then reload the page, or just a div with the content you want from the html (or JSON) in the return data of the ajax call.
The advantage of the Ajax approach is that you could specify a different Action on a different Controller for the various parts of the page you wanted to update.
Nima,
you can do it via partial views or render action, and json to display data
the basic example is as example here:
http://www.asp.net/mvc/tutorials/iteration-7-add-ajax-functionality-cs
or very popular option is display action for the task in jquery.dialog()
depends on you what way you want to proceed
cpo
revised:
My bad.
From logic point of view, it is as this:
It depends only on you, which way you want to go.
(From my point of view)
Benefits of separating the logic is :
simple to understand as controller is related only to actions for eg: orders
Can be used on more places if you need
Easy to test only small items, eg one testcase/fixture to controller for only orders
Usefull for more complicated projects
On the other hand
Keep everything in one controller and split the logic by regions
Eveything is together, easy to see other methods and what they do
Hope this is what you were looking for
cpo