How to check for invalid route in layout view - zend-framework2

I have this piece of code written in Application/view/layout/layout.phtml for adding a link which will be pointing to current page. This I added for debugging purpose for refreshing the current page.
<li class="active"><?php echo $this->translate('Refresh') ?></li>
This is working fine as long as I don't invalid route (404 error). I get below fatal error
Fatal error: Uncaught exception 'Zend\View\Exception\RuntimeException'
with message 'No RouteMatch instance provided'
I wan't to handle this by adding a condition to check if its a 404 error or an invalid route before trying to render the url. I am not sure how to do it. I tried to look the source code of Zend\View\View class and ViewModel class to see if there is a way I can get error code or something which can tell its a 404 error.
Edit:
As a last resort I have adding the try catch block like below which is working fine but want to check if there is any elegant way
<?php
try{
$url = $this->url();
?>
<li class="active"><?php echo $this->translate('Refresh ') ?></li>
<?php
} catch (Exception $ex) {
}
?>

The exception message you are getting is not because the route is undefined but rather that the routeMatch parameter of the URL view helper, Zend\View\Helper\Url, has not been set.
Normally when using the URL helper you can provide the name of the route as the first argument. The helper will internally use the router and route match to generate the correct URL string based off the route configuration.
For example
echo $this->url('test'); // will create the route matching the test route name
The helper also allows you to provide no route name, $this->url(), in which case it will use the last matched route by default when creating theses routes. There is however one special case when you cannot rely on this; when the application cannot match a route, there will be no RouteMatch available.
So using this shorthand convenience method in the layout.phtml when the application tries to load the 404 error template (which is wrapped by the layout.phtml) the URL view helper will have no RouteMatch available and throw the error you received.
To fix this you should always provide a route name when calling the URL view helper in the layout or error scripts.

Related

MapRoute for passing a parameter to the root of the site causing JavaScript errors on certain script references

I am using this code to map a route for the root of my site.
routes.MapRoute("InstanceLogIn", "{InstanceParameter}",
new { controller = "Account", action = "Login" });
So the URL will be similar to "MySite/SomeParameter" and this will route it to the log in page and pass the parameter.
This works but the issue is when i deploy this site some script references don't work, it seems for some reason they are also using this route.
For example this reference is not returning the script but instead following the route and therefore throwing a JavaScript error
"MySite/ScriptResource.axd?d=UsKo6CSewZbLohzBYSPi2REunQLB9VJ1DCCMF8dLkLy"
For some reason this script works fine however in my development environment. It is definitely the route that is causing the error as if i remove it the script resources are correctly called. What could be the reason for this?
You need to explicitly ignore this route so that MVC does not try to route anything with .axd. Simply add:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}")

Route to default not found 'catch all' address

I'm trying to route URLs like stats/non-existent-page to a default 'not found' page, where I'd like to display a 'Did you mean' suggestion along with a not found message, how can I route all non-existent URLs to a default controller/action?
Something like:
match 'stats/*path' => 'default#non_existent'
Add this after your other 'stats/..' urls , This will route your all stats/* paths to the controller action mentioned with path variable you can use to determine your 'did you mean' suggestion..

(How) can I pass POST arguments from one cherrypy page class to another?

Following Cherrypy's tutorial, it seems fairly easy to receive data from a form "within" a page class. Now, i have tried to pass the arguments to another page class's index page like the following:
In my root index page I have the following form:
<form action="otherpage" method="post">
<input type="text" name="arg1">
...
</form>
while the receiving page's class is like:
class OtherPage:
def index(self, arg1=None):
return arg1
and it is mounted like
root.otherpage = Otherpage()
It always shows a blank page, regardless of what I put in the form, so I guess it doesn't get the parameter "arg" passed correctly. Do you see what's wrong?
When you submit a request for 'otherpage', then CherryPy does attempt to use your Otherpage.index method to handle the request. However, there are two things happening:
By default, the trailing slash Tool is on, with the following defaults: trailing_slash(missing=True, extra=False, status=None, debug=False). This means that, if you request the URI otherpage?arg1=foo, which is missing a trailing slash, then CherryPy will add the trailing slash and redirect the client to request otherpage/?arg1=foo instead. Note that (because the 'extra' arg is False by default) the reverse is not true: otherpage/ will not redirect to otherpage.
There's an additional wrinkle, however, because the request is POST and not GET. CherryPy raises a 303 or 302 redirect (depending on which version of HTTP your client supports) and that's probably not what you want for redirecting POST. See http://docs.cherrypy.org/dev/refman/_cperror.html#redirecting-post for the full discussion.
You should either:
add the trailing slash in your HTML if you can,
set tools.trailing_slash.missing = False in config (in which case I believe the index method will just serve the resource without a redirect, or
supply a more appropriate "status" argument to the trailing slash Tool if you have control over client behavior.
Tried CherryPy for the first time today and encountered exactly the same problem. I think that Otherpage isn't matched correctly because the resulting URI lacks a trailing slash.
Try
<form action="otherpage/" method="post">
...

ASP.NET MVC 2 parameters throws JS error

My application works fine when I have only one parameter.
e.g.
/Product/Index/2
/Report/Sales/08-2009
But it failes when I add one more part to the url. Let's say I want to add the end month-year parameter to the url routing. Mow it becomes:
/Report/Sales/05-2009/09-2009
I do get both parameters in my action method. I parse it and retrieve the data and pass the Model to the View. With this scenario it throws the client side JS error when I try to access any of the form elements. I get "object expected" error. The same view works fine using just first parameter. What could be the issues here?
I also loose the CSS styles when this error occurs.
Thanks
well, without seeing any code at all this is difficult to troubleshoot, but I'd say it's likely because you are referencing your javascript and css files using a relative path like:
../content/scripts/myjavascript.js
Adding the second url parameter has caused the browser to be unable to find the urls because you have added what looks like an extra level of depth to the url.
You should provide absolute urls to your scripts and css files. An easy way to do this is to use the "ResolveUrl" method like so:
<%= ResolveUrl("~/Content/Scripts/myjavascript.css") %>

Issue with Default and catchall routes

I define a lot of explicit routes. One of them is:
routes.MapRoute("default", "",
new { controller = "Home", action = "Index" });
At the end, I define a catchall route:
routes.MapRoute("PageNotFound", "{*url}",
new { controller = "Error", action = "Http404" });
If I go to the homepage http://localhost, then the http404 page is shown. And strangely, if I remove the catchall route, then the welcome page appears correctly.
Note also that I have a menu where I call Url.RouteUrl("default") and the link to the homepage is correctly generated.
So, why is my default route not activated when the catchall route exists?
Update: I'm using routes.RouteExistingFiles=true. If I remove it, then it works as expected. But I need it to be set to true. What's the problem here?
Thanks.
If you use "routes.RouteExistingFiles=true" it means it will route existing (physically exist) files as its own - so routing will be skipped for those. I think in your root website there is probably a "default.aspx" or "index.htm" or something like that.
Turning on RouteExistingFiles will then allow those files to be executed normally (instead of via routing).
Now I think what happen is that your catchall routing is overriding you RouteExistingFiles - so it automatically routes the default.aspx into your 404 catchall.
If you still have the default route (I.E. {controller}/{action}/{id}) in RegisterRoutes() it will trap all URLs that match the format of a normal MVC request.
In other words the catch-all route can only intercept a bad URL if it doesn't fit the normal format (blah/blah/blah/blah).
In the case of a non-existent controller the exception must be handled through conventional ASP.NET handling.
Theres a good description of handling this here
Did you try to put a constraint on the catch all route? Constraint should tell it that the catch-all segment should not have 0 characters.

Resources