I am trying to learn Umbraco MVC and I am stuck with a problem I cannot seem to work out. I want to create a page containing a table, with clickable table-headers. When clicking on a table-header, the table is sorted according to the header.
My idea is to render the table in a partialview. The table header-links should be generated using Html.RenderActionLink, which reference an action in a SurfaceController (or RenderMvcController), that returns a sorted list of content.
This is my setup:
View
@inherits UmbracoTemplatePage<DocumentType>
...code...
@{ Html.RenderPartial("ListAllAssignments", TempData["viewModel"] ?? new AssignmentViewModel(Model)); }
PartialView - ListAllAssignments.cshtml:
@inherits UmbracoViewPage<AssignmentViewModel>
<div>
<table>
<tr>
<td>
@Html.ActionLink("[ID]", "SortBy", "AssignmentSurface", new { nodeId = Model.CurrentPage.Id, sortCategory = SortCategory.ID }, null)
</td>
</tr>
table data here
</table>
</div>
Controller:
public class AssignmentSurfaceController : SurfaceController
{
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult SortBy(int nodeId, SortCategory sortCategory)
{
var overviewPage = DocumentTypeHelper.GetDocument<AssignmentOverviewPage>(nodeId);
var assignmentViewModel = new AssignmentViewModel(overviewPage);
var assignments = new AssignmentManager().GetAll();
switch (sortCategory)
{
case SortCategory.ID:
assignments = assignments.OrderBy(x => x.ID);
break;
default:
return null;
}
assignmentViewModel.AllAssignments = assignments.ToList();
TempData["viewModel"] = assignmentViewModel;
return RedirectToCurrentUmbracoPage();
}
}
However, clicking the header in the table results in an error:
Cannot find the Umbraco route definition in the route values, the request must be made in the context of an Umbraco request
Hi jho,
Whats happening here is that the surface controller dosent know what page you coming from and cant return "CurrentUmbracoPage" with the Html.ActionLink.
I would solve this using a RenderMvcController and pass in the sorting category to it and from the controller return a custom RenderModel to get rid of your TempData fields.
Create a RenderMvcController naming it: Document Type name = controller name Template name = action name and create a view model
public class HomeController : Umbraco.Web.Mvc.RenderMvcController
{
public ActionResult HomePage(RenderModel model, int sort)
{
var viewModel = new HomePageViewModel(model.Content)
{
Sort = sort
};
return base.Index(viewModel);
}
}
public class HomePageViewModel : RenderModel
{
public HomePageViewModel(IPublishedContent content)
: base(content)
{
}
public int Sort { get; set; }
}
Then you can use a Html.Action to render your partial. Like this:
@Html.Action("SortBy","AssignmentSurface", new { nodeId = Model.Content.Id, sortCategory = Model.Sort })
And finally in your Surface controller return the partialview:
public class AssignmentSurfaceController : SurfaceController
{
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult SortBy(int nodeId, SortCategory sortCategory)
{
var overviewPage = DocumentTypeHelper.GetDocument<AssignmentOverviewPage>(nodeId);
var assignmentViewModel = new AssignmentViewModel(overviewPage);
var assignments = new AssignmentManager().GetAll();
switch (sortCategory)
{
case SortCategory.ID:
assignments = assignments.OrderBy(x => x.ID);
break;
default:
return null;
}
assignmentViewModel.AllAssignments = assignments.ToList();
TempData["viewModel"] = assignmentViewModel;
return PartialView("ListAllAssignments", assignmentViewModel);
}
}
The parameters dictionary contains a null entry for parameter 'sort' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult AssignmentOverviewPage(Umbraco.Web.Models.RenderModel, Int32)' in 'AssignmentOverviewPageController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
I did not change anything in the routing-table so far - but maybe I have to?
This is my RenderMvcController:
public class AssignmentOverviewPageController : RenderMvcController
{
public ActionResult AssignmentOverviewPage(RenderModel model, int sort)
{
var viewModel = new AssignmentViewModel(model.Content)
{
Sorting = sort
};
return base.Index(viewModel);
}
}
public ActionResult HomePage(RenderModel model, int? sort) {
if(sort != null)
// add value to your model like this (int)sort
}
else {
// set the default sort value to the model
}
}
The questionmark after the int will allow sort to be null.
Calling controller action from partial view
First time poster, long time reader :)
I am trying to learn Umbraco MVC and I am stuck with a problem I cannot seem to work out. I want to create a page containing a table, with clickable table-headers. When clicking on a table-header, the table is sorted according to the header.
My idea is to render the table in a partialview. The table header-links should be generated using Html.RenderActionLink, which reference an action in a SurfaceController (or RenderMvcController), that returns a sorted list of content.
This is my setup:
View
PartialView - ListAllAssignments.cshtml:
Controller:
However, clicking the header in the table results in an error:
Cannot find the Umbraco route definition in the route values, the request must be made in the context of an Umbraco request
What am I doing wrong?
Best regards
Hi jho ,
You have to try define exactly url of request. Did you change something in routing ?
Thanks
Hi jho, Whats happening here is that the surface controller dosent know what page you coming from and cant return "CurrentUmbracoPage" with the Html.ActionLink.
I would solve this using a RenderMvcController and pass in the sorting category to it and from the controller return a custom RenderModel to get rid of your TempData fields.
Create a RenderMvcController naming it: Document Type name = controller name Template name = action name and create a view model
Then you can use a Html.Action to render your partial. Like this:
And finally in your Surface controller return the partialview:
Your sorting urls would now look like this:
Good luck!
Hi Cimplex
Thank you for your suggestion! It almost works :)
However, now I am recieving this exception:
I did not change anything in the routing-table so far - but maybe I have to?
This is my RenderMvcController:
This is the view of my RenderMvcController:
Hi jho,
Try this:
The questionmark after the int will allow sort to be null.
Making sort nullable solved it.
Thank you very much for the help - appreciated :)
I'll mark your first post as the answer since that contains the majority of the changes I had to perform.
Dow anybody knows where i can find the DocumentTypeHelper from this example?
is working on a reply...