ReturnUrl in RouteConfig.Cs not working - asp.net-mvc

In my MVC project I Use this code in RouteConfig.Cs
routes.MapRoute(
name: "Signin",
url: "login/{ReturnUrl}",
defaults: new { controller = "Account", action = "Signin", ReturnUrl = UrlParameter.Optional }
);
but url not workin well when i'm browsing the signin page from another page for example:
localhost:43773/account/signin?ReturnUrl=anotherpage
i expect : localhost:43773/login/anotherpage
how can i fix this?

I understand what you are expecting. But ASP.NET MVC does NOT generate URLs based on the route(s) you define. That would be both unnecessary and would incur an overhead.
If it is really important for you to have a URL like localhost:43773/account/login/anotherpage, then you could look into IIS URL Rewrite Module.
Here is an example of how you can achieve what you want to do
<rewrite>
<rules>
<rule name="Standardize Log In Url" stopProcessing="true">
<match url="^account/signin?ReturnUrl=([0-9a-z]+)" />
<action type="Rewrite" url="account/login/{R:1}" />
</rule>
</rules>
</rewrite>
NOTE This solution is untested, so you may need to make some modifications to it.

Related

How can I force all IIS requests to go to one MVC controller & action?

I have a situation that I figured would be quite easy to do in MVC.
I want to have all request on a IIS site end up going to one specific action.
So I added the following to my route
routes.MapRoute(
"Everything",
"{*foo}",
new { controller = "Home", action = "Index" }
);
That works for most request going to the server, but there are some things the are ending being dealt with by other handlers:
http://foo.com/ (works)
http://foo.com/bar (works)
http://foo.com/bar/baz (works)
http://foo.com/bar/baz.txt (works - used to not work, but started working after adding runAllManagedModulesForAllRequests="true" in web.config)
http://foo.com/bar/baz. (does not work. stumped as to why)
This is in MVC 5, but I don't think that should really make a difference to the solution.
What trick am I missing here?
I would use the url rewrite module for this. Something like this should do it. (Obviously, change the url to whatever you want):
<rewrite>
<rules>
<rule name="Catch-All" stopProcessing="true">
<match url=".*" />
<action type="Rewrite" url="/index.html" appendQueryString="false" />
</rule>
</rules>
</rewrite>

MVC routing for both .mvc and extensionless URLs

I have an odd question. I'm working on some MVC code that was setup to run extensionless, as in /Home/Index?id=10 However, it used to be setup for IIS 6, and was using the .mvc extension on all the controllers, as in /Home.mvc/Index?id=10.
I would like both routes to be able to work. In my global.asax.cs file, I created the following code:
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("Default2",
"{controller}.mvc/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute("Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
This almost worked! But unfortunately when my controllers return RedirectToAction, the URL which is generated fails.
I call RedirectToAction like this:
return RedirectToAction("Index", "Account");
and it returns this:
/Account.mvc
Now Index is assumed so I'm not worried that that's missing. However, there is no / on the end of that URL, and because of that, it is returning a 404 error. If I add the / it works fine. Is there some way I can help MVC to generate the URLs correctly, or is there a way I can modify the routes to make it recognize this URL?
Background: I'm in this situation because I began converting my application to use extensionless URLs after we upgraded our webserver to IIS 7.5. I didn't realize that there were alot of links into the applications which had been shared with the outside world--changing to extensionless broke all those links. Doh! Should've left well enough alone.
I would personally use the URL Rewriter. You can Redirect ASP.NET Legacy URLs to Extensionless with the IIS Rewrite Module.
So for example you could create an outbound rules that looked something like (not exactly, they definitely need testing):
<outboundRules>
<rule name="remove .mvc outbound 1">
<match serverVariable="RESPONSE_LOCATION"
pattern="^/(.*).mvc$" />
<action type="Rewrite" value="/{R:1}" />
</rule>
<rule name="remove .mvc outbound 2">
<match filterByTags="A, Form, IFrame, Img, Input, Link, Script"
pattern="^/(.*).mvc$" />
<action type="Rewrite" value="/{R:1}" />
</rule>
</outboundRules>
If someone decided to hardcode an MVC extension...
<rule name="Add Slash Inbound">
<match url="(.*)" />
<conditions>
<add input="{PATH_INFO}" pattern="^/(.*).mvc$" negate="true" />
</conditions>
<action type="Rewrite" url="{R:0}/" />
</rule>
Looks like here is coded your solution with adding / at end of each requests Add a trailing slash at the end of each url?. If it is not enough We can try something else :)
For anyone trying to figure this out: the problem may not be that RedirectToAction is generating a bad URL, but actually that the URL is not being interpreted properly by IIS.
I discovered that other servers had no problem with the missing slash in the URLs described in the original question.
This led me to look at the App Pool setting. One setting in particular seems to affect this: "Enabled 32-bit applications". Setting this to true on the Application Pool enabled my application to parse URLs which were missing the trailing '/'.
Weird huh?

ASP.NET MVC 4 - 301 Redirects in RouteConfig.cs

How can I add a route to the RouteConfig.cs file in an ASP.NET MVC 4 app to perform a permanent 301 redirect to another route?
I would like certain different routes to point at the same controller action - it seems a 301 would be best practice for this, specially for SEO?
Thanks.
You have to use RedirectPermanent, here's an example:
public class RedirectController : Controller
{
public ActionResult News()
{
// your code
return RedirectPermanent("/News");
}
}
in the global asax:
routes.MapRoute(
name: "News old route",
url: "web/news/Default.aspx",
defaults: new { controller = "Redirect", action = "News" }
);
I know you specifically asked how to do this on the RouteConfig, but you can also accomplish the same using IIS Rewrite Rules. The rules live on your web.config so you don't even need to use IIS to create the rules, you can simply add them to the web.config and will move with the app through all your environments (Dev, Staging, Prod, etc) and keep your RouteConfig clean. It does require the IIS Module to be installed on IIS 7, but I believe it comes pre installed on 7.5+.
Here's an example:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Redirect t and c" stopProcessing="true">
<match url="^terms_conditions$" />
<action type="Redirect" url="/TermsAndConditions" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>

asp.net mvc does not receive the GET request with a period in it

I'm using .net4.5rc with MVC4.0rc
The code below is taken from a MVC webapi application but I the same behaviour is there for reular asp.net mvc
My registerroutes code looks like this
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "R1",
routeTemplate: "product/{id}",
defaults: new {
controller="Product",
id = RouteParameter.Optional
}
);
This works well with Ids that doesn't have a period in them. However when I ask for a product with a period in it, the call does not seem to get to ASP.NET
when I use the setting below as suggested on similar posts it works when there is a trailing /
But it doesn't work without it
in summary
http://mysite.com/product/AZ0 //works
http://mysite.com/product/AZ.0/ //work with relaxedUrlToFileSystemMapping
http://mysite.com/product/AZ.0 //does not work
The response is 404 and I guess this is returned by IIS without involving ASP.NET.
When I run routedebugger with a URL like the last one above, I don't even get the routedebugger stuff
How do I make IIS to pass the control to ASP.NET when there is a URL with a pattern:
mysite.com/product/{id} regardless of whether there is a period in the id or not.
thanks.
Let me answer this myself. Adding a URL Rewrite solves the problem.
The code below added to the web.config tells to rewrite the Url with a trailing "/" if the URL is of the form (product/.) Then it is no longer handled as a file but handled as regular MVC.
<system.webServer>
....
<rewrite>
<rules>
<rule name="Add trailing slash" stopProcessing="true">
<match url="(product/.*\..*[^/])$" />
<action type="Rewrite" url="{R:1}/" />
</rule>
</rules>
</rewrite>
</system.webServer>

How to move a URL for a ASP.NET MVC Site

My SEO colleague has fired in a few url requests that involve moving
www.mydomain.co.uk/news
www.mydomain.co.uk/news/{id}/{title}
to
www.mydomain.co.uk/uk-news
www.mydomain.co.uk/uk-news/{id}/{title}
What is the best way to carry this out.
I was just thinking of changing the route in the global.asax file
FROM:
routes.MapRoute(
"News", // Route name
"News", // URL with parameters
new { controller = "News", action = "Index" } // Parameter defaults
);
TO:
routes.MapRoute(
"News", // Route name
"uk-news", // URL with parameters
new { controller = "News", action = "Index" } // Parameter defaults
);
and setting up a 301 redirect on the basic www.mydomain.co.uk/news
Is there a better way to do this?
I don't think so. Your on the right track, changing the URL on the route and doing the 301 permanent redirect is the way to go. For the 301 try using the URL Rewrite Module.
Rewrite Module
<!-- Web.config file in subdirectory to be redirected -->
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="RedirectRule" stopProcessing="true">
<match url="(.*)" ignoreCase="true" />
<action type="Redirect" url="http://www.newdomain.com/{R:1}" redirectType="Permanent" />
<conditions>
<add input="{HTTP_HOST}" pattern="www\.old-domain\.com" />
</conditions>
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
ISAPI_Rewrite
RewriteCond Host: ^mydomain\.co.uk
RewriteRule /news http://www.mydomain.co.uk/uk-news [I,O,RP,L]
I (ignore case)
Indicates that characters are matched regardless of a case. This flag affects RewriteHeader directive and all corresponding RewriteCond directives.
O (nOrmalize)
Normalizes string before processing. Normalization includes removing of an URL-encoding, illegal characters, etc. Also, IIS normalization of an URI completely removes query string. So, normalization should not be used if query string is needed. This flag is useful with URLs and URL-encoded headers.
RP (permanent redirect)
Almost the same as the [R] flag but issues 301 (moved permanently) HTTP status code instead of 302 (moved temporary).
L (last rule)
Stop the rewriting process here and don't apply any more rewriting rules.

Resources