I'm making a site using Umbraco 7.6.6 and I want to access a third party database of my client. For that I've made a custom controller named QuestionsController
. Inside this I've created an action:
public class QuestionsController : SurfaceController
{
private QuestionService _questionService = new QuestionService();
[HttpGet]
public ActionResult Index()
{
return PartialView("~/Views/MacroPartials/Questions.cshtml", _questionService.ReadFile());
}
}
This page index page works fine and is called by this code on the view of my document type:
Html.RenderAction("index", "Questions");
Overview page (just an image):
Here is my model I've created
public class Question
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public User User { get; set; }
public DateTime Created { get; set; }
public List<Comment> Comments { get; set; }
}
Now I'll to create a details page with more information on the front side.
[HttpGet]
[Route("~/questions/details/{id}")]
public ActionResult Details(int id)
{
return View(_questionService.ReadFile().ElementAt(id));
}
Redirecting to that page I'll do like this:
<a href="~/questions/details/@q.ID">@q.Title</a>
But this doesn't work at all. The detail page gives me a 404 (page not found) error.
My question is now: How could I create custom URLs like ~/questions/details/{id}
without a document type? Could anyone help me?
Here is a guide:
Make your controller and extends from Controller
instead of SurfaceController
and return a JsonResult
instead of a ActionResult
:
public class QuestionsController : Controller
{
private QuestionService _questionService = new QuestionService();
[HttpGet]
public JsonResult Index()
{
return Json(_questionService.ReadFile());
}
}
Add the controller path to umbracoReservedPaths
appSettings
key in your web.config
file. Any path added to this list will be ignored by Umbraco’s routing engine.
<add key="umbracoReservedPaths" value="~/umbraco,~/install/,~/questions/" />
global.asax.cs
Change or add your global.asax.cs
to inherit from UmbracoApplication
. Open up your global.asax.cs
file and change this line:
public class MvcApplication : System.Web.HttpApplication
to this:
public class MvcApplication : UmbracoApplication
global.asax
Change your global.asax
to inherit from your application. This was the big gotcha that caught me out and I had to do quite a bit of searching to find it! Open up your Global.asax
file (right click on it and View Markup) and change this line:
<%@ Application Codebehind="Global.asax.cs" Inherits="Umbraco.Web.UmbracoApplication" Language="C#" %>
to this:
<%@ Application Codebehind="Global.asax.cs" Inherits="MyProject.MvcApplication" Language="C#" %>
where MyProject
in this example is the base namespace of your project.
RouteConfig.cs
Remove the default custom route from RouteConfig.cs
if exists. If you don’t remove this route, MVC will try and route every request and your website will show en empty page which may be a nice clean design, but not very functional!
Register your custom route in the RegisterRoutes
method of your RouteConfig.cs
. If this file doesn't exist, create one under the folder App_Start
. You have to do this for each route you want use:
routes.MapRoute("Default", "{controller}/{action}/{id}", new {
controller = "Questions",
action = "Index",
id = UrlParameter.Optional
});
OnApplicationStarted
Finally you need to add an OnApplicationStarted
override method to global.asax.cs
. This will allow you to add your application to read the RegisterRoutes
method in your RouteConfig.cs
file when it starts, and add the custom route you just set up into your application:
protected override void OnApplicationStarted(object sender, EventArgs e)
{
base.OnApplicationStarted(sender, e);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
When this steps are done remove next line and the file. This you didn't need anymore.
Html.RenderAction("index", "Questions");
Create views for each action. You could do this like the classic MVC applications.