Urlrewrite in asp.net - asp.net

i am currently using IIS7's Url Re-write module, but the main loophole of using the IIS7's url re-write module, is that i have to write rule for all the page,which i want to use on the website, i want to use a comman rule and redirect it to particular page (say homepage) and using global.asax i can redirect it to desired page...
Is it possible with url re-write or is there any tool available i can use for this purpose, or a code sample that could help me doing this.
i dont want extension in the url.
i have pages like index.aspx, news.aspx, artists.aspx, lessons.aspx... i want the urls like index, news, lessons, artists, i created a rule in web.config like
< rewrite>
< rules>
< rule name="urlType1">
< match url="^(\w*)" />
< action type="Rewrite" url="default.aspx" appendQueryString="false" />
< /rule>
< /rules>
< /rewrite>
this will land any page to default.aspx, and then using rawUrl in the global.asax, i am checking for the page like if user has entered "news" then i rewrite to news.aspx
Hope this has helped.

You can do just as you're suggesting in your question--redirect all requests to a single URL:
And then in your Global.asax you could call Server.Transfer( "~/file1.aspx" ) to forward the request to a particular file.
Or, you could transfer directly from your URL Rewrite rule and skip further processing in your Global.asax file. For instance, this rule will read the incoming URL that has no file extention, and then forward the request on to a file that has a file extension:
<rule name="Append a file extension to all requests discard querystring" stopProcessing="true">
<match url="^(.*)\?" />
<action type="Rewrite" url="{R:1}.aspx" />
</rule>
Read more about URL Rewriting rules on Ruslan Yakushev's blog at http://ruslany.net/.

[EDIT] Okay, so for what you are asking...as far as I know, you do need to create a specific rewrite rule for each page. I was thinking more along the lines of MVC, where when you go to:
/news
it routes to
/default.aspx
which calls the NewsController.Index and displays the news page from default.aspx. However, to actually break everything out into individual pages and just trying to remove the extension...as far as I know, you have to create a new rule for each instance.
Redirect rules can be configured from the web.config files.
E.g. Here's what WordPress does in the web.config file that's included with WordPress:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="wordpress" patternSyntax="Wildcard">
<match url="*"/>
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
</conditions>
<action type="Rewrite" url="index.php"/>
</rule></rules>
</rewrite>
</system.webServer>
</configuration>
The routes ALL traffic to the index.php page. The index.php file then reads what the URL is and spits out data based on the URL. It doesn't redirect it to a different page after the redirect, it--rather--decides what content to display.
MVC works along the lines of, you see this url:
/news > will call > NewsController.Index();
/news/index > will call > NewsController.Index();
/news/view > will call > NewsController.View();
/news/read/id > will call > NewsController.Read(id);
These Controllers, then typically get data from the database and apply the data to a "View" (html page that sits somewhere on the server with variables to display the data the controller passes to it).

Related

Redirect arbitrary request to directory to particular page in ASP.Net

That title isn't very descriptive, but I couldn't figure out how to phrase my question very well. What I'm trying to do is use a single page to interpret multiple URLs. Here's an example: [domain]/name-of-question.aspx is clearly not a file on the site's server, and yet the server acts like it is. This behavior makes pages much more readable and more easily bookmark-able.
My vision for the solution is to be able to have to server redirect a request to a certain directory to a particular page, whilst appending the name of the page requested to the page as a URL parameter. Here's what I mean: [domain]/questions/name-of-question redirects to [domain]/question.aspx?page=name-of-question.
This is how reddit does their self posts, I think, but they don't use ASP.Net or IIS.
Is this possible, and if so, how would one implement this behavior? If there's any code you write, please write it in C#, because I don't know VB.Net very well. Thanks!
You need to use URL rewriting to accomplish this.
You have to create a rewrite rule that rewrites any requests to [domain]/questions/{1}
to [domain]/question.aspx?{1}
In ASP.NET you have the URL Rewriter module: http://www.iis.net/downloads/microsoft/url-rewrite
The rule might look similar to this and is applied in the web.config file:
<rewrite>
<rules>
<rule name="RewriteUserFriendlyURL1" stopProcessing="true">
<match url="questions/(.*)" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="question.aspx?{R:1}" />
<serverVariables>
<set name="{RESPONSE_CONTENT_TYPE}" value="image/png" />
</serverVariables>
</rule>
</rules>
</rewrite>
EDIT: To change the content type, add the serverVariables section in the rewrite rule and authorise that variable to be set in IIS manager:
If you are using ASP.NET 4.0+, then this might be worth a read, as ASP.NET Routing and URL Rewriting are not necessarily competing technologies, but potentially complementary features.
URL Rewriting vs. ASP.NET Routing

Sitefinity CMS URLs and IIS URL Rewriting

I have a site that is being served out of Sitefinity CMS, at http://www.example.com/, I also have sites on the same server that are being served out of the same root location that are accessed as follows: http://www.example.com/sub-site/. All of these sub-sites are in php and resolve to specific php files such as index.php. There are a lot of these sub-sites and we're looking to remove a number of them from the server. We usually send variables in the get request to these sub-sites as follows: http://www.example.com/sub-site/?address=12&ID=22
What we want to do is set up a rewrite rule that will redirect incoming requests to non-existent sub-sites to an error page written in PHP. This rewrite rule should keep the query string intact so that we can still use those variables once the error page is reached.
Here is the re-write rule that we have:
<rewrite>
<rules>
<rule name="RedirectFileNotFound" stopProcessing="true">
<match url=",*" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Redirect" url="errorpage.php" appendQueryString="true" />
</rule>
</rules>
</rewrite>
So this rewrite rule works terrific, in fact, it works too well. When I go to the Sitefinity site's home page all is well, but when I click on any of the links on that page, I'm redirected to the error page. I've determined that the problem has to do with dynamic server content as the Sitefinity site links look like this http://www.example.com/order/ or http://www.example.com/info/. These directories don't exist and thus, the rewrite rule catches them each time.
Is there a way that I can redirect the subsites without having the sitefinity site respond the same way?
I found this S.O. post that is addressing a similar problem, but I was unable to find much assistance there.

A very simple IIS7 redirect to different path

I have had a site at www.mysite.com/myfolder/ for years. I have developed a new version and want to just remove the /myfolder so that the site serves all pages from www.mysite.com.
Example: www.mysite.com/myfolder/mypage.htm will be permanently redirected to www.mysite.com/mypage.htm
How do I configure this using the URL Rewrite module in IIS7? I start with a blank rule, but then get lost. Thanks.
You either use the IIS Management UI or edit the web.config directly. With a section in web.config that looks like this, you will redirect everything (images as well), which might be want you want.
<system.webServer>
<rewrite>
<rules>
<rule name="test" stopProcessing="true">
<match url="^myfolder/(.*)" />
<action type="Redirect" url="{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
If you use the Management tool, you add an empty rule, give it a name, add ^myfolder/(.*) as the pattern, select Redirect as action type, add {R:1} as target URL and select 301 as redirect type.
This is supposed to be permanent, that's why you should use a 301 redirect (for SEO purposes and so on).

Error when reprocessing a rewritten url in IIS URL Rewrite 2

I'm trying to create a system to serve images and their resized versions from GridFS using MVC3 and IIS URL Rewrite 2. After testing, I've realized that serving images directly from filesystem is 10x faster than serving them using GridFS file streams. Then I've decided to keep the originals in GridFS and create a copy of the original file and resized versions on servers local file system using a combination of Url Rewrite 2 and Asp.Net handlers.
Here are the rewrite rules I use for serving the original and the resized version:
<rule name="Serve Resized Image" stopProcessing="true">
<match url="images/([a-z]+)/[a-f0-9]+/[a-f0-9]+/[a-f0-9]+/([a-f0-9]+)-([a-f0-9]+)-([a-f0-9]+)-([0-9]+)\.(.+)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="/Handlers/ImageResizer.ashx?Uri={REQUEST_URI}&Type={R:1}&Id={R:2}&Width={R:3}&Height={R:4}&ResizeType={R:5}&Extension={R:6}" appendQueryString="false" logRewrittenUrl="true" />
</rule>
<rule name="Serve Original Image" stopProcessing="true">
<match url="images/([a-z]+)/[a-f0-9]+/[a-f0-9]+/[a-f0-9]+/([a-f0-9]+)\.(.+)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="/Handlers/Images.ashx?Uri={REQUEST_URI}&Type={R:1}&Id={R:2}&Extension={R:3}" appendQueryString="false" logRewrittenUrl="true" />
</rule>
As you can see, rewrite engine checks if the file exist on the file system, and if not. rewrites the url and sends the request to the handler. Handler serves the stream and writes the file to the file system. On the next request, file is served directly from file system. I've seperated the files to folders by splitting their 24 char IDs (MongoDB Object ID as string) to avoid hunderds of thousands images in same folder.
Here is a sample original image request:
http://localhost/images/test/50115c53/1f37e409/4c7ab27d/50115c531f37e4094c7ab27d.jpg
This and the resized versions works without any problems.
Since this URL is too long and has duplicates in it, I've decided to use rewrite engine again to shorten the url to generate folder names automatically. Here is the rule which I put to the top:
<rule name="Short Path for Images">
<match url="images/([a-z]+)/([a-f0-9]{8})([a-f0-9]{8})([a-f0-9]{8})(.+)" />
<action type="Rewrite" url="images/{R:1}/{R:2}/{R:3}/{R:4}/{R:2}{R:3}{R:4}{R:5}" appendQueryString="false" logRewrittenUrl="true"></action>
</rule>
When I request an image using this rule for example with the following URL:
http://localhost/images/test/50115c531f37e4094c7ab27d.jpg
it only serves the image if the image is already on filesystem, otherwise I get the following error:
HTTP Error 500.50 - URL Rewrite Module Error.
The page cannot be displayed because an internal server error has occurred.
I've checked IIS Log File Entry for the request. It doesn't show any details except:
2012-08-02 14:44:51 127.0.0.1 GET /images/test/50115c531f37e4094c7ab27d.jpg - 80 - 127.0.0.1 Mozilla/5.0+(Windows+NT+6.1;+WOW64)+AppleWebKit/537.1+(KHTML,+like+Gecko)+Chrome/21.0.1180.60+Safari/537.1 500 50 161 37
On the other hand, successfull requests log the rewritten URL's like:
GET /Handlers/ImageResizer.ashx Uri=/images/test/50115c53/1f37e409/4c7ab27d/50115c531f37e4094c7ab27d-1f4-1f4-2.jpg&Type=test&Id=50115c531f37e4094c7ab27d&Width=1f4&Height=1f4&ResizeType=2&Extension=jpg
Elmah and EventLog also doesn't show anything. Added a filesystem logger to the top of my controller method and it doesn't log these particular problematic requests.
Can anyone suggest a workaround to get it work?
Edit: After RuslanY's suggestion about Failed Request Tracing, I've managed to identify the error:
ModuleName: RewriteModule
Notification: 1
HttpStatus: 500
HttpReason: URL Rewrite Module Error.
HttpSubStatus: 50
ErrorCode: 2147942561
ConfigExceptionInfo:
Notification: BEGIN_REQUEST
ErrorCode: The specified path is invalid. (0x800700a1)
Entire Trace Result can be see here (IE only)
Unfortunately, this is still not taking me to the solution since the second rule (therefore shortening rule) is working when the file exist on the file system.
As an alternative approach to using UrlRewrite to do this checking, why not using Application Request Routing w/ disk based caching. Dynamic images will be generated, and the caching infrastructure of ARR will save generated images to disk. Less mess, and I've used ARR to great success in production scenarios. Disk cache persist between IIS restarts and can live as long as you say (default is to use cache information from the response, but you can override this to be longer).
Application Request Routing

IIS URL Rewrite rule - Default document for subdirectories

I would like create URL rewrite rule that will set default document for my virtual folders. eg. someting like this
www.domain.com/en/ -> www.domain.com/en/index.aspx
www.domain.com/hr/ -> www.domain.com/hr/index.aspx
www.domain.com/de/ -> www.domain.com/de/index.aspx
directories en, hr, de doesn't really exists on web server they are just markers for languange used in site used by home grown http module that will rewrite path with query params.
Quick solution was define rule for every single lang, something like this :
<rewrite>
<rewriteMaps>
<rewriteMap name="Langs">
<add key="/en" value="/en/index.aspx" />
<add key="/hr" value="/hr/index.aspx" />
<add key="/de" value="/de/index.aspx" />
</rewriteMap>
</rewriteMaps>
<rules>
But I would really like solution that would not require changes in web.config and adding rewrite rule for every languange used on particular site.
Thanks !
<rule name="Lang-Redirect">
<match url="^(\w{2})\/?$" />
<action type="Rewrite" url="{R:1}/index.aspx" />
</rule>
That should allow you to capture the language tag from the request and rewrite it to your custom http handler.

Resources