I am working on building an MVC frontend for a CMS system. The CMS system will serve ASP.NET MVC with pages and content.
In Global.asax I registered a custom route handler like this:
public class MvcApplication : EPiServer.Global
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.Add(new Route("{*data}", new MvcRouteHand开发者_StackOverflow社区ler()));
}
protected void Application_Start()
{
ControllerBuilder.Current.SetControllerFactory(new MvcControllerFactory());
ModelBinders.Binders.Add(typeof(MvcPageData), new PageDataModelBinder());
RegisterRoutes(RouteTable.Routes);
}
}
This is how my route handler looks like:
public class MvcRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new MvcRequestHandler(requestContext);
}
}
And my MVC request handler:
protected void ProcessRequest(HttpContext httpContext)
{
List<string> pageParams;
// Get the requested page from the CMS
EPiServer.UrlBuilder internalUrlBuilder = GetInternalUrl(httpContext.Request.RawUrl, out pageParams);
MvcPageData mvcPage =
CurrentPageResolver.Instance.GetCurrentPage(internalUrlBuilder.QueryCollection["id"] ??
string.Empty);
string controllerName = mvcPage.ControllerName;
if (pageParams.Count == 0)
{
mvcHandler.RequestContext.RouteData.Values.Add("action", "Index");
}
else
{
mvcHandler.RequestContext.RouteData.Values.Add("action", pageParams[0]);
}
mvcHandler.RequestContext.RouteData.Values.Add("controller", controllerName);
mvcHandler.RequestContext.RouteData.Values["data"] = mvcPage; // This works fine, but I also want to add the remidning pageParams
IController controller = ControllerBuilder.Current.
GetControllerFactory().CreateController(mvcHandler.RequestContext, controllerName);
controller.Execute(mvcHandler.RequestContext);
}
This is what a controller looks like today:
public class StandardController : Controller
{
public ActionResult Index(MvcPageData currentPage)
{
return View(currentPage);
}
}
My problem is that I want to be able to pass more than one parameter to the controller, so I will need to change the mvcHandler.RequestContext.RouteData.Values["data"] to contain some kind of list of parameters. I have searched but not found an solution to the problem, maybe it is really simple. The resulting controler might look something like this:
public ActionResult Index(MvcPageData currentPage, int id, string name)
Anyone knows how to do this? Thanks.
You can try to create array of objects with items count pageParams.Count and add to it the mvcPage object and all objects from pageParams except the first one (which is your action name).
I had missunderstood how the model binding works in MVC. I thought all the data sent to the controller had to be defined in ProcessRequest before calling controller.Execute, which not is the case.
Have you tried registering the handler in the Web.config?
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="yourApiUrlPrefix/*"
type="MvcRouteHandler, YourAssemblyName" />
</httpHandlers>
</system.web>
</configuration>
精彩评论