How to get original url after HttpContext.RewritePath() has been called - asp.net

I am working on a web app which makes use of a 3rd party HttpModule that performs url rewriting.
I want to know if there's any way to determine the original url later on in Application_BeginRequest event. For example...
Original url:
http://domain.com/products/cool-hat.aspx
Re-written url (from 3rd party httpmodule):
http://domain.com/products.aspx?productId=123
In the past I have written HttpModules that store the original url in HttpContext.Items but, this is a 3rd party app and I have no way of doing that.
Any ideas would be appreciated.

Try this:
string originalUrl = HttpContext.Current.Request.RawUrl;
The original URL is inside of this property.

I had the same problem, but I wanted the fully qualified URL (RawUrl gives you just the Path and Query part). So, to build on Josh's answer:
string originalUrlFull =
Page.Request.Url.GetLeftPart(System.UriPartial.Authority) +
Page.Request.RawUrl

I know this question was asked long time ago. But, this is what I use:
System.Uri originalUri = new System.Uri(Page.Request.Url, Page.Request.RawUrl)
Once you have the URI you can do a ToString() to get the string, or cal any of the methods/properties to get the parts.

Create a new HttpModule to serve as a wrapper around (inherits) the third party module and do whatever you want with it.
In your case, override the appropriate function (ProcessRequest?) and store the original url in HttpContext.Items, and then call the MyBase implementation. Should work fine.

Related

Send query string parameter from a non-web application

Ok, I've been bugging with this for too long.
I need to call my website from a rough VB.net app. Then only thing I need is to attach a query string parameter to the calling url, so I can distinguish the pages to be shown to different VB app users.
So I want to click a button and launch that website, giving this parameter.
First I was bugging with adding the system.web libraries. Now I can't use Request/Response.QueryString as well.
I tried getting some example help from this post. but as I said before - I cannot make use of Request.QueryString as I cannot import it.
I am stuck here:
Process.Start("http://localhost:56093/WebSite1?id=")
I need to attach a query string parameter to the url and then open the website with that url.
Can someone just give me a sample code for my problem.
Query parameters are parsed by the web server/http handler off the URL you use to call the page. They consist of key and value pairs that come at the end of the URL. Your code is nearly there. Say you needed to pass through the parameters:
ID = 1234
Page = 2
Display = Portrait
Then you'd turn them into a URL like this:
http://localhost:56093/WebSite1?ID=1234&Page=2&Display=Portrait
Therefore in your code you'd have:
Process.Start("http://localhost:56093/WebSite1?ID=1234&Page=2&Display=Portrait");

How to Generate absolute urls with https in MVC3?

I am using MVC3 and am trying to serve content from https, the problem is that when I call Url.Content the files are still served from http using a relative url. I thought this problem was addressed in MVC3 but i can't seem to find any solution. Does anybody know if this issue is inherently solved in MVC3 and how to accomplish it or do I need to create my own helper methods to generate absolute Urls based on protocol?
You can probably implement your own solution using VirtualPathUtility.ToAbsolute. Probably something like this:
public static class UrlHelperExtension {
public static string Absolute(this UrlHelper url, string relativeOrAbsolute) {
var uri = new Uri(relativeOrAbsolute, UriKind.RelativeOrAbsolute);
if (uri.IsAbsoluteUri) {
return relativeOrAbsolute;
}
// At this point, we know the url is relative.
return VirtualPathUtility.ToAbsolute(relativeOrAbsolute);
}
}
which you would use like:
#Url.Absolute(Url.Content("~/Content/Image.png"))
(Didn't test this myself, feel free to play around to make it work right.)
This helps to you to generate absolute URLs for your content files. In order to change the scheme of the resulting URLs, you can create an additional extension method that manipulates the scheme of the given URLs so that they are HTTPS, or something else.
As Khalid points out in the comments, similar extension methods are already available in various open-source projects which you can make use of (given that the license permits). An example one can be found here.
A solution that doesn't use extension methods or hardcode the protocol, as suggested by #BlackTigerX:
Url.RouteUrl("Default", new { Action = "About" }, Request.Url.Scheme)
as suggested in the following article: http://captaincodeman.com/2010/02/03/absolute-urls-using-mvc-without-extension-methods/
You can use Url.RouteUrl, some of the overloads take a protocol parameter, looks something like this:
Url.RouteUrl("Product", new { itemId = "123456" }, "https");
Take a look a the overloads and see which one you can use
If you don't want to "build" the url and just want the full path of the current page, this will do the trick
Context.Server.UrlEncode(Context.Request.Url.AbsoluteUri)
I know it's not as elegant as an Extension Method but thought of sharing it for educational purposes

IgnoreRoute with webservice - Exclude asmx URLs from routing

Im adding the filevistacontrol to my asp.net MVC web application.
I have a media.aspx page that is ignored in the routing with
routes.IgnoreRoute("media.aspx");
This works successfully and serves a standard webforms page.
Upon adding the filevistacontrol, I can't seem to ignore any calls the control makes to it's webservice.
Eg the following ignoreRoute still seems to get picked up by the MvcHandler.
routes.IgnoreRoute("FileVistaControl/filevista.asmx/GetLanguageFile/");
The exception thrown is:
'The RouteData must contain an item named 'controller' with a non-empty string value'
Thanks in advance.
Short answer:
routes.IgnoreRoute( "{*url}", new { url = #".*\.asmx(/.*)?" } );
Long answer:
If your service can be in any level of a path, none of these options will work for all possible .asmx services:
routes.IgnoreRoute("{resource}.asmx/{*pathInfo}");
routes.IgnoreRoute("{directory}/{resource}.asmx/{*pathInfo}");
By default, the parameters in a route pattern will match until they find a slash.
If the parameter starts with a star *, like pathInfo in those answers, it will match everything, including slashes.
So:
the first answer will only work for .asmx services in the root path, becasuse {resource} will not match slashes. (Would work for something like http://example.com/weather.asmx/forecast)
the second one will only work for .asmx services which are one level away from the root.{directory} will match the first segment of the path, and {resource} the name of the service. (Would work for something like http://example.com/services/weather.asmx/forecast)
None would work for http://example.com/services/weather/weather.asmx/forecast)
The solution is using another overload of the IgnoreRoute method which allows to specify constraints. Using this solution you can use a simple pattern which matches all the url, like this: {*url}. Then you only have to set a constraint which checks that this url refers to a .asmx service. This constraint can be expressed with a regex like this: .*\.asmx(/.*)?. This regex matches any string which ends with .asmx optionally followed by an slash and any number of characters after it.
So, the final answer is this:
routes.IgnoreRoute( "{*url}", new { url = #".*\.asmx(/.*)?" } );
I got it to work using this (a combo of other answers):
routes.IgnoreRoute("{directory}/{resource}.asmx/{*pathInfo}");
What happens when you use:
routes.IgnoreRoute("FileVistaControl/filevista.asmx");
If that doesn't work, try using the ASP.NET Routing Debugger to help you:
http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx
Try this:
routes.IgnoreRoute("{*filevista}", new { filevista = #"(.*/)?filevista.asmx(/.*)?" });
This is based on a Phil Haack recommendation stated here.
Have you tried:
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
routes.IgnoreRoute("{resource}.asmx/{*pathInfo}");
It would help if you posted the source for your route configuration. I'm going to take a shot in the dark and say to make sure that your IgnoreRoute() calls are all at the top of your routing definition.
The way IgnoreRoute works is to create a route that matches the ignored route URL and constraints, and attaches a StopRoutingHandler as the RouteHandler. The UrlRoutingModule knows that a StopRoutingHandler means it shouldn't route the request.
As we know, the routes are matched in the order of which they are defined. So, if your {controller}/{action}/{id} route appears before your "FileVistaControl/filevista.asmx/GetLanguageFile/" route, then it will match the "{controller}/{action}/{id}" route.
I may be totally off base here, but it's hard to know without seeing your source. Hope this helps. And post source code! You'll get better answers.

URLRewriting challenge

I'm using URLRewritingNet 2.0. How do I rewrite URL's in ASP.NET?
Here is the request:
Input: www.sampleweb.com/param1/value1/param2/value2/default.aspx
Output: www.sampleweb.com/default.aspx?param1=value1&param2=value2
It must work dynamically like this param1/value1/param2/value2/ ... /paramN/valueN
That is not a good way to pass key/value pairs.
You should assume the key based on the values position. That makes life a lot easier. HttpContext.RewritePath (with its variations) is how you go about transforming the url.
So...basically you can't do this in the "rewrite" node in your web.config file using ASP.Net's URL Rewriter.
But you could do it elsewhere in your code (an HTTP Module, or Begin Request, or whatever). To transform you URL's you could do something like this:
string strRegex= #"/([^/]*)/([^/]*)";
RegexOptions myRegexOptions = RegexOptions.None;
Regex myRegex = new Regex(strRegex, myRegexOptions);
string strTargetString = #"/param1/value1/param2/value2/param3/value3/param4/value4";
string strReplace = #"$1=$2&";
If you combine that with matching the filename (here's the RE):
(.*)/([^/]*\..*)$
And then re-composing the complete URL--then you could Server.Execute or whatever (if on your own server) or otherwise proxy over to where you want this processed. Yup, it's a little ugly, but if you don't have control of the shape of the request coming at you, this is a way to transform it.

ASP.NET: Get *real* raw URL

In ASP.NET, is there any way to get the real raw URL?
For example, if a user browse to "http://example.com/mypage.aspx/%2F", I would like to be able to get "http://example.com/mypage.aspx/%2F" rather than "http://example.com/mypage.aspx//".
I would of course like a clean way to do it, but I can live with a hacky approach using reflection or accessing obscure properties.
At the moment, I try to use the uri in the Authorization-header (which works), but I cannot rely on that always being there.
EDIT:
What I really want to do is to be able to distinguish between "http://example.com/mypage.aspx/%2F" and "http://example.com/mypage.aspx/%2F%2F".
It looks like ASP.NET first converts "%2F%2F" into "//" and then converts the slashes into a single slash.
So just re-encoding it is not going to work.
I wasn't able to test this because it only works in IIS and not the ASP.NET Development Server that is part of Visual Studio, but try:
Request.ServerVariables[ "HTTP_URL" ]
The following code works for me:
IServiceProvider serviceProvider = (IServiceProvider)HttpContext.Current;
HttpWorkerRequest workerRequest = (HttpWorkerRequest)serviceProvider.GetService(typeof(HttpWorkerRequest));
string realUrl = workerRequest.GetServerVariable("HTTP_URL");
Note that this only works when running on the IIS and not under f.x. ASP.NET Development Server!
Thanks to Lucero for the answer in another thread and Zhaph for pointing me to the thread.
See also:
Get the exact url the user typed into the browser
Server.HtmlEncode(Request.RawUrl);
The raw URL is defined as the part of the URL following the domain information. In the URL string http://www.contoso.com/articles/recent.aspx, the raw URL is /articles/recent.aspx. The raw URL includes the query string, if present.
see also:link text
I can't test here, but this might be what you need:
Request.Url.AbsoluteUri
Request.RawUrl will return the application relative path(including querystring info) while Request.Url will return the complete path(including querystring info).
For more information, see "Making sense of ASP.NET paths".
Well, you could just encode it back to the url-encoded version.
Get the url from the request and urlencode only the query string part and then concatenate them

Resources