I am using the following code to achieve something like domain.com/actionName1, domain.com/actionName2 and so on to reach actions that reside in home controller.
routes.MapRouteLowercase("DefaultRoutes",
"{action}",
new { controller = "Home" },
new { action = new homeActionConstraint() });
It works fine. But how do I stop user from entering domain.com/home/actionName1 etc. and still reaching the action instead of 404 or something?
You need to remove the default {controller}/{action}/{id} route that matches that URL.
(or constrain it to not match)
take out the default route, just delete it and everything will stop working the normal way or you can map the default root to the 404 page you desire, however that is a little strange even for SO
Related
I tried to understand how the routing in CodeIgniter work.
I want to use normal access to sides which are not a kind of user area or something special - only normals links in the main root of the website.
So I try this.
I've set in the routes.php
$route['/'] = "index";
I've created controller names Frontend.php and a model named Frontend_modell.php
The Controller (nothing to do)
public function index()
{
redirect(site_url('index'));
}
The Modell
public function __construct()
{
parent::__construct();
}
I've added an index.php inside the view-folder Frontend and I add the index.php (for test) in the main folder from appilation and in the view folder.
If I try to access www.domain.com I see the URL will change to www.domain.com/index, but no side will come up. "the page you requested was not found."
What I do wrong ? I hope somebody can explain to me how it works correctly and why.
First of all routes uses controller_name/method_name and here you tried to use method_name directly.
Secondly, most of cases you don't need to play with routes unless you need a special handler or rerouting, so mostly keep it to default.
Btw the url rerouted to www.domain.com/index cause it looked for a controller named index as you specified and there in no controller found with that name it should be frontend if that's your controller.
The reason for the problem was from another point.
The Controller i've create had some bugs, after checking the function of the CR Controller, the routing works fine :-))
Say I have an route with a param like this (in Angular 2): /user1/products/:id, which could have child routes like /user1/products/3/reviews.
When I navigate to /user1/products/-1, I check with my server and if the product doesn't exist, I want to render a 404 page without affecting the browser history.
Using router.navigate(['/404']) or router.navigateByUrl('/404') doesn't seem to work because it adds both /user1/products/-1 and/404 to the browser history.
Meaning when I press the Back button in the browser, I go back to /user1/products/-1 which is immediately redirected to /404 and I'm essentially stuck at /404.
In ExpressJS, we would do something like next() to pass the request to our 404 handler. Is there a client-side equivalent in Angular 2?
Update
In the new Router V3 you can use guards as explained in https://angular.io/guide/router#canactivate-requiring-authentication
Original
I think you should use #CanActivate() to do the check. If you forward in #CanActivate() the invalid URL shouldn't be added to the history (not tried)
See also https://github.com/angular/angular/issues/4112 for how to use DI in #CanActivate()
Ok, this is already implemented, just not well-documented.
According to the docs:
router.navigateByUrl(url: string, _skipLocationChange?: boolean) : Promise<any>
Has a parameter _skipLocationChange that will not modify the history.
These will do the trick:
router.navigateByUrl('/404', true);
router.navigateByInstruction(router.generate(['/404']), true);
As of Angular 2 final this is the solution:
this._router.navigateByUrl('/404', { skipLocationChange: true })
Its really interesting question, perhaps you should report it as feature request. I would be nice to have access to router instruction inside loader callback of RouteDefinition.
You could try to emulate validation adding default route /** and using regex parameter of RouteDefinition to match only positive numbers.
I have limited knowledge so beat me up as needed.
I have created a controller using the EF with ASPX(C#) views. I inherited this setup.
The PK in the target table/EF is an actual URL. So when you click the link ActionLink feeds the URL and I receive a 404.
Html.ActionLink("Edit", "Edit", new { id=item.ImagePath })
So id= /foldername/foldername2/image.jpg
This causes the browser to try and load the resource.
Can someone give me a clue how to process this "id" accordingly?
Have you changed your routing to accept this sort of id?
If not then you will need to go into your global.asax.cs file and edit the map routes.
This should help you with that:
Creating custom routes
The EDIT action in the controller... is waiting for a string ID or Integer one?
If the EDIT action accepts strings, then you could just scape the ID's "/"... that way the routing engine will no think the ID is a URL.
I am trying to dynamically create a sitemap for my site and I wan't it to be (I believe it is necessary to have it) located at the root level, ie. Domain.com/sitemap.xml
So far I have an action result in the home controller like this:
public ActionResult SiteMap()
{
...
return this.Content(xml, "text/xml");
}
This works fine for creating the file but it is located at Domain.com/Home/Sitemap and my understanding is the the sitemap is supposed to be located at the root level. Is there a way to rewrite the url or add a new route for it in the Global.asax file? By default the Global.asax file contains this:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
So it seems like this may be the place to add something like a check if the requested route is Sitemap.xml and just redirect it to Home/sitemap (or just serve the sitemap right there). I'm not sure how to do this, if it is possible, as I have never messed around with the RegisterRoutes section.
Another problem that may arise would be the extension .xml, I would think that IIS would think this is a file on the drive and ignore the route all together.
Am I going down the correct path, or is there a better way to do this? Or is it not possible and I have to just physically create the file?
Edit (Solved)
I just occurred to me that I have been thinking about this the wrong way. All I would have to do is have a method to create/update a sitemap file and save it to /sitemap.xml periodicity or every time a page is added. I can't believe this wasn't obvious to me.
You could add a route:
routes.MapRoute(
"sitemap",
"sitemap.xml",
new { controller = "Home", action = "SiteMap" }
);
and make sure that you put this route before your default route.
This might be slightly off topic, (but in the same breath, kind of close... I think) Have a look at MVCSitemapProvider.
It's simple enough to use in a project, I started using it lately and it works like a charm. I can add some code samples if you do end up wanting to go this route?
I'm very new to MVC and I'm trying to get a new site set up using it. For SEO reasons we need to make the url of a page something like "Recruiter/4359/John_Smith" or basically {controller}/{id}/{name}. I have that working when I create the url in the code behind like so...
//r is a recruiter object that is part of the results for the view
r.Summary = searchResult.Summary + "... <a href=\"/Recruiter/" + r.Id + "/" + r.FirstName + "_" + r.LastName + "\">Read More</a>"
But when I am using the collection of results from a search in my view and iterating through them I am trying to create another link to the same page doing something like <%=Html.ActionLink<RecruiterController>(x => x.Detail((int)r.Id), r.RecruiterName)%> but that doesn't work. When I use that code in the view it gives me a url in the form of /Recruiter/Detail/4359 I was told by a coworker that I should use the Html.ActionLink to create the link in both the view and the controller so that if the route changes in the future it will automatically work. Unfortunately he wasn't sure how to do that in this case. So, my problems are...
How can I make the Html.ActionLink work in the view to create a url like I need (like r.Summary above)?
How do I use the Html.ActionLink in a controller instead of hardcoding the link like I have above?
I came across this blog post which got me going in the right direction.
http://www.chadmoran.com/blog/2009/4/23/optimizing-url-generation-in-aspnet-mvc-part-2.html
It is a good idea to use the ActionLink method to write out links as your coworker says, that way they will always match your routes.
In your current case the reason it is writing out the method is because it is based on the default routing. You can fix this by adding another route above the default one in the Global.asax. You just need to stipulate the format you want like this:
routes.MapRoute(
"Recruiter",
"Recruiter/{id}/{name}",
new { controller = "Recruiter", action = "Details" }
);
MVC will work through your routes in the order they are registered so putting this before the default will make it use your route instead.
EDIT:
You might find this route debugging tool useful.