I made a new "LoginRoute" controller, and pointed my route to that:
RouteTable.Routes.MapUmbracoRoute(
"OrderDetails",
"login/order/{orderNum}",
new
{
controller = "LoginRoute",
action = "OrderDetails",
itemID = UrlParameter.Optional
},
new FindOrderRouteHandler()
);
Apparently you can't have this:
public ActionResult OrderDetails(RenderModel model, string orderNum)
{
//Code
}
public ActionResult ValidateLogin(RCS_CustomerContact model)
{
//Code
}
In the same surfacecontroller when one ActionResult is used in a custom route.
Are the any recommended way of creating Controllers for custom routes?
I will have to make a few more, so I'm wondering if I should simply make a "CustomRoute" controller, and let that handle all custom routes.
But that means that my code will be spilt up, so all Actions related to Login will not be placed in the LoginController, since a few will be in the CustomRouteController.
I've been working on this today and I have found this is my solution too if I don't want to hack into Umbraco's source code. Not ideal, but there are worse things in the world. I kept the two controllers in the same file too to make sure it was easier to find.
But I did hack into Umbraco's source code and can see why the error appears.
When you post back to say Blah/SaveStuff, Umbraco searches for the right route.
If it finds more than 1 route that matches e.g.
1. The SurfaceController you set up called Blah.
2. The CustomRoute you set up which specifies Blah.
it then tries to find the route with the action you've specified.
But because both the SurfaceController route is generic it hasn't named your postback Action in the route data and the CustomRoute is to work on a specific action only then neither of these match and the logic fails and throws the error.
So, imho, the error message is wrong because it did find the controller, it just couldn't find the action you were posting to in the Route table - the route table shouldn't hold all actions otherwise it'd be unwieldy and to me this is where Umbraco falls down a bit. It is expecting all actions to be in the data it finds.
The real solution would be for the code to say "well I found 2 (or more) routes with for this Controller but none of them are a direct match for the controller/action pair... I do however have a generic SurfaceController route I should use that and if after this the action isn't available, the developer can fix that."
So that's what I did:
Umbraco V8
RenderRouteHandler.cs
Line 197
I added:
if(surfaceRoute == null)
{
// we couldn't find the specific one, so let's just default to the generic surface controller route which is always the first one in the list...
surfaceRoute = surfaceRoutes.FirstOrDefault();
}
And it now works. I think I will submit a PR for this.
Could not find a Surface controller route in the RouteTable for controller name Login
I have this small login function
And this partial
The user goes to www.mysite.com/login/ Here he sees the login partial, fills it out and login.
This works perfectly fine. No problem what so ever... Subpages like "profile" and "orderhistory" also works fine.
Now I need to add a custom route to /login/order/[orderNum] so the user can click an order in "history" and see the details.
So I added this Route (I also have a route to product details)
So now I have a route, and can browse to /login/order/123 and see the order. Perfect...
But now my login doesn't work. What?? I can go to /login/ and see the login form, but when I try to login I get this error:
If I remove the route my login works again:
Can someone tell me why? And what to do to fix it?
I am kind off new to Umbraco. Only worked with it for a few months.
Ok.. I found a workarround.
I made a new "LoginRoute" controller, and pointed my route to that:
Apparently you can't have this:
In the same surfacecontroller when one ActionResult is used in a custom route.
Are the any recommended way of creating Controllers for custom routes? I will have to make a few more, so I'm wondering if I should simply make a "CustomRoute" controller, and let that handle all custom routes. But that means that my code will be spilt up, so all Actions related to Login will not be placed in the LoginController, since a few will be in the CustomRouteController.
I've been working on this today and I have found this is my solution too if I don't want to hack into Umbraco's source code. Not ideal, but there are worse things in the world. I kept the two controllers in the same file too to make sure it was easier to find.
But I did hack into Umbraco's source code and can see why the error appears.
When you post back to say Blah/SaveStuff, Umbraco searches for the right route.
If it finds more than 1 route that matches e.g. 1. The SurfaceController you set up called Blah. 2. The CustomRoute you set up which specifies Blah. it then tries to find the route with the action you've specified.
But because both the SurfaceController route is generic it hasn't named your postback Action in the route data and the CustomRoute is to work on a specific action only then neither of these match and the logic fails and throws the error.
So, imho, the error message is wrong because it did find the controller, it just couldn't find the action you were posting to in the Route table - the route table shouldn't hold all actions otherwise it'd be unwieldy and to me this is where Umbraco falls down a bit. It is expecting all actions to be in the data it finds.
The real solution would be for the code to say "well I found 2 (or more) routes with for this Controller but none of them are a direct match for the controller/action pair... I do however have a generic SurfaceController route I should use that and if after this the action isn't available, the developer can fix that."
So that's what I did:
Umbraco V8 RenderRouteHandler.cs Line 197
I added:
And it now works. I think I will submit a PR for this.
Have you checked Umbraco Route hijacking?
is working on a reply...