I have imprelemnted a complex url rewrite to translate user frendly url into internal application url.
So basically if you go to my site (an ecommerce) :
"https://some_domain/en/shoes/some_brand/article-description-written-in-a-firendly-manner_articleCode"
Then the url is rewritten into the internal version "https://some_domain/Products.aspx?id=articleCode&languageCode=en"
The viceversa also is true, when an internal URL need to be produced and placed into the page, it's rewritten into it's "external" shape.
Everything work just fine, until someone will change the language (eg : from 'en' to 'de').
Language change like many other parameter change is applied on query string, so changing language will trigger a page refresh with the trailing parameter into query string.
So 'en' to 'de' in the previous url will casue the following call :
"https://some_domain/en/shoes/some_brand/article-description-written-in-a-firendly-manner_articleCode?languageCode=de"
Then even if server-side i consider the language to be german, how i can rewrite the url displaied into the browser?
It should become something similar to :
"https://some_domain/de/schuhe/some_brand/artikelbeschreibung-freundlich-geschrieben_articleCode"
Should i calculate the new external URL and do a 302 redirect (HttpResponse.Redirect)?
Or is a better option put the precalculated url as link in the language change button?
Related
I want to redirect a user to an external site, outside of my ASP.NET MVC application, through a simple anchor tag. The tricky part is, the user can enter the link himself.
up up and away!
If the user enters: www.google.com in a field (bad user), he is being redirected to http://www.example.com/page/www.google.com.
which is totally understandable, he should use http:// in front of his link...
It works as expected if I hardcode the http://in front of the link like so: up up and away!
BUT if the user was to enter http://www.google.com (good user), the browser redirects to http://http//www.google.com which goes nowhere..
So now the question: Is there a helper or method or something that routes to an external site no matter if the link contains http://or not? Something like #Url.ExternalLink(model.Url) would be great.
I could write this myself, but no need to reinvent the wheel, right? So if the wheel exists, please provide the wheel! Thanks in advance!
Checked a bunch of links, but they didn't satisfy my needs of the variable user input (never trust a user!):
How to properly encode links to external URL in MVC Razor ,
Redirect to external url from OnActionExecuting? ,
Why does Response.Redirect not redirect external URL? ,
url.Action open link in new window on ASP.NET MVC Page , ...
Your use case is quite specific, MVC framework doesn't have any extension methods for this.
You need to develop it by yourself. You have the following options:
Create extension method (as you mentioned) for UrlHelper class - #Url.ExternalLink(model.Url)
Create extension method for HtmlHelper - #Html.ExternalLinkFor(model => model.Url)
As url comes from your model you can validate/modify it before passing to View. In this case up up and away! will still be valid.
Add regex validator to a View where user types in url
You can easily extend UrlHelper with a method:
public static string ExternalLink(this UrlHelper helper, string uri)
{
if (uri.StartsWith("http://")) return uri;
return string.Format("http://{0}", uri);
}
Examples
#Url.ExternalLink("http://google.com")
#Url.ExternalLink("google.com")
routes.MapPageRoute("Main", "", "~/index.aspx");
thats the route I mapped on index page..
when I call the url with index.aspx it displays like
www.abc.com/index.aspx
but I want it to show
www.abc.com
even when index.aspx is called
Regarding my comment, URL Rewrite is also available in IIS and Asp.net. So you can potentially use it.
Another solution would be to redirect to your route. The route alone doesn't change the URL, it just allows you to access the resource via the defined route.
You can redirect to the route though, which will rewrite the URL on the client
For example like this:
if (Request.Path != "/")
{
Context.Response.RedirectToRoute("Main");
}
This is very simplified and might not work in all scenarios, so please be very careful.
I need to change the URL on my address bar.
I looked for URL Rewrite but as far as I've seen it works for a request like this:
url.com/mypage.aspx?xp=asd&yp=okasd
and transforms that into:
url.com/mypage/asd/okasd
http://www.iis.net/downloads/microsoft/url-rewrite
That's not my scope. I already have MVC Routes working with url.com/mypage. The problem is that when I type that URL I am redirected (that's the behavior I want) to url.com/otherpage/actionX?param=value. The problem is that I still want the address bar to show url.com/mypage. Will URL Rewrite work for that?
I am asking because I don't know if it will work since it's an internal redirect (RedirectToAction) instead of a 'regular' access.
In case someone wonders why I can't make a route for that, as explained in my question I alread have one rule for that url.com/mypage that redirects to a 'router' which decides what action to call.
I've seen some questions, but I don't think they cover my specific problem:
MVC3 change the url
C# - How to Rewrite a URL in MVC3
UPDATE
This is my route:
routes.MapRoute(
"Profile", // Route name
"{urlParam}", // URL with parameters
new { controller = "Profile", action = "Router" } // Parameter defaults
);
Inside Router action I redirect to the correct action according to some validation done on urlParam. I need this behavior since each action returns a different View.
Updated my tags since I am now using MVC4
Thanks.
I once had to run a php site on a windows box. On the linux box it originally ran, it had a rewrite defined to make site process all request in only one php file (index.php).
I've installed and configured URL Rewrite with following parameters
Name : all to index.php
Match URL ------------------------------
Requested URL : Matches the Pattern
Using : Regular Expressions
Pattern : (.*)
Ignore Case : Checked
Conditions -----------------------------
Logical Grouping : Match All
Input : {REQUEST_FILENAME}
Type : Is Not a File
Action ---------------------------------
Action Type : Rewrite
Action Properties:
Rewrite Url : /index.php?$1
Append Query String : Checked
Log Rewritten URL : Checked
this makes all requests to site (except files like css and js files) to be processed by index.php
so url.com/user/1 is processed on server side as url.com/index.php?/user/1
since it works on server side client url stays same.
using this as you base you can build a rewrite (not a redirect).
Server.Transfer is exactly what you need, but that is not available on MVC.
On the MVC world you can use the TransferResult class defined in this thread.
With that... you add code to your ROUTE action that process the urlParam as always and instead of "redirecting" (RedirectToAction) the user to a new URL, you just "transfer" him/her to a new action method without changing the URL.
But there it a catch (I think, I have not tested it)... if that new page postbacks something... it will NOT use your router's action URL (url.com/mypage), but the real ACTION (url.com/otherpage)
Hope it helps.
In my opinion,you can try following things:
Return EmptyResult or RedirectResult from your Action method.
Also,you need to setup and construct outbound route for URL that you required.
Secondly, if these didn't work,the crude way to handle this situation is with Div tag and replacing the contents of Div with whatever HTML emitted by Action method. I am assuming here that in your problem context, you can call up jquery ajax call.
Hope this Helps.
The problem you have is that you redirect the user ( using 302 http code) to a new location, so browser ,reloads the page. you need to modify the routes to point directly to your controller. The route registration should be routes.MapRoute("specific", "my page", new { controller = "otherpage", action="actions", param="value"}).
This route should be registered first
In the global.asax of my website project (not MVC, not Web Application) MapPageRoute won't let me map to a page with an extension.
For example:
routes.MapPageRoute("GetMobilePassForAttendee", "Pass/Attendee/{attendeeId}", "~/GetMobilePass.aspx");
works as expected, but
routes.MapPageRoute("GetMobilePassForAttendee", "Pass/Attendee/{attendeeId}/pass.pkpass", "~/GetMobilePass.aspx");
returns a 404.
Anyone know why?
Perhaps I should be using URL rewriting, but all the material I've read has suggested I use routing instead.
Have you tested the "pass.pkpass" page separately, let say attendeeid=1 to see if Pass/Attendee/1/pass.pkpass is a working page without the routing?
Because .NET routing would not work in this case if this is a working page. It will skip the routing and load the actual "Pass/Attendee/1/pass.pkpass" page.
This worked for me:
routes.MapPageRoute("FederationMetadataRoute", "FederationMetadata/2007-06/{file}", "~/FederationMetadata/2007-06/FederationMetadata.aspx")
And then I just check the {file} parameter to make sure it equaled FederationMetadata.xml
So in your case, just set Pass/Attendee/{attendeeId}/pass.pkpass to Pass/Attendee/{attendeeId}/{pkpass}
and check {pkpass} to make sure it equals pass.pkpass on your page.
How can I set up my page load event in my code behind to redirect to an url that has an https prefix? I would need it to work with urls that have query strings attached too.
It's one thing to construct a link that goes straight to the https page, but I don't want the user to be able to manually change it to an http page.
Also I don't want to do it with javascript because it might be turned off.
I'm guessing a regular expression?
We mark our SSL Required pages with a special attribute ForceSslAttribute. Then we have a HttpModule that pulls down the current page's class and inspect it's attributes.
If the attribute is present on the page, it takes the exact url that was passed and changes the protocol from http to https then calls a redirect.
There's probably a bit simpler way of doing it, but that's how it's done for us.
Attribute:
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)]
public sealed class ForceSslAttribute : Attribute
{
// Marker Attribute
}
Page Example (CodeBehind):
[ForceSsl]
public partial class User_Login : Page
{
//...
}
You can figure out the type of the page like this:
HttpContext.Current.CurrentHandler.GetType()
All Page's implement IHttpHandler and when you're visiting a page, it'll work.
The cool part about this method is you can mark anything that's an IHttpHandler and it'll force the redirect too :)
Add this at the top of your Page_Load
if (Request.ServerVariables["HTTPS"] != "ON")
{
Response.Redirect("https://" + Request["HTTP_HOST"] + Request.RawUrl);
}
I use the following in Global.asax Application_BeginRequest
If needsSSL <> Request.IsSecureConnection Then
If needsSSL Then
Response.Redirect(Uri.UriSchemeHttps + Uri.SchemeDelimiter + Request.Url.Host + Request.Url.PathAndQuery, True)
Else
Response.Redirect(Uri.UriSchemeHttp + Uri.SchemeDelimiter + Request.Url.Host + Request.Url.PathAndQuery, True)
End If
End If
There is an IIS7 module for URL rewriting. Very handy, but you need access to the IIS and it requires some time to learn how to write the rules. A simple http->https rule is a matter of seconds.
Just be careful because any rules you add will be stored in your web.config, so don't delete/override it or you will have to write them again.
Forcing SSL using ASP
To force SSL using ASP, follow these steps:
Click Start, click Run, type Notepad, and then click OK.
Paste the following code into a blank Notepad document. On the File menu, click Save As, and then save the following code in the root of your Web server as an include file named ForceSSL.inc:
<%
If Request.ServerVariables("SERVER_PORT")=80 Then
Dim strSecureURL
strSecureURL = "https://"
strSecureURL = strSecureURL & Request.ServerVariables("SERVER_NAME")
strSecureURL = strSecureURL & Request.ServerVariables("URL")
Response.Redirect strSecureURL
End If
%>
For each page that requires SSL, paste the following code at the top of the page to reference the include file from the previous step:
<%#Language="VBSCRIPT"%>
<!--#include virtual="/ForceSSL.inc"-->
When each page is browsed, the ASP code that is contained in the include file detects the port to determine if HTTP is used. If HTTP is used, the browser will be redirected to the same page by using HTTPS.