My UrlRewrite IHttpModule remove my second QueryString - c#

I have a custom url rewriter function that works fine. But when i are going to use a second querystring on my url, that remove the second querystring.
my friendly url: /gallery/view-ablum/?q=1
i the code: Page.aspx?id=22&q=1 , when i have past RewritePath(...) the remove &q=1 from my real page. I don't now who to fix this, i can't figure it out.
context.RewritePath(ci.PageUrl + ta + "&q=" + q, false);
Is there a IsPostBack for IHttpModule?

for the question, "Is there a IsPostBack for IHttpModule"
bool isPostBack = !string.IsNullOrEmpty(context.Request.Form["__VIEWSTATE"])
..or introduce your own hidden field when not using viewstate (which is probably safer anyway)

Is there a IsPostBack for IHttpModule?
Will depend on which event the module is subscribing to. Earlier HttpApplication events will occur before IsPostBack is determined.
But IsPostBack is WebForm specific (e.g. not used in ASP.NET MVC) is may not be available outside the Page class.

Well i get this error code when i debugg : CurrentNotification 'context.CurrentNotification' threw an exception of type 'System.PlatformNotSupportedException' System.Web.RequestNotification {System.PlatformNotSupportedException}
and i found this
- Base ( "For this operation requires IIS integrated pipeline mode.") System.SystemException (System.PlatformNotSupportedException)

Related

Session is null in AcquireRequestState when loading virtual directory name in browser, but not null when loading Default.aspx

I have an ASP.NET 4.0 WebForms application. I need to access HttpContext.Current.Session and set a value in the AcquireRequestState event (or an event after it) in Global.asax, and I've found a peculiar behavior.
Let's say I have a virtual directory in IIS (version 7 in my case) called Foo. In that I have Default.aspx as the home page. A sample Global.asax file is below:
<%# Application Language="C#" %>
<script runat="server">
void Application_AcquireRequestState(object sender, EventArgs e)
{
HttpContext.Current.Session["key"] = "value";
}
</script>
When I visit http://localhost/Foo/Default.aspx in my browser, it works just fine. When I visit http://localhost/Foo/ I get a NullReferenceException where I set the value on the session. The only change is the URL in the browser. They end up hitting the same page, but the framework behaves differently based on whether or not the URL contains just a folder name, or if it contains an aspx file.
Checking if (HttpContext.Current.Session != null) is not an option for me, because I need to set a value on the session with every request, which is non negotiable.
Is there a config setting in IIS that I'm missing, or is this a bug/forgotten feature?
An answer for another question hinted at the fact IIS does not load the session for every kind of request, for example style sheets don't need a session. Maybe this behavior is happening because IIS can't tell ahead of time if that folder name will result in executing an aspx file or if it will deliver a static HTML file?
Update: I even tried re-ordering the default documents that IIS looks for so that "default.aspx" was at the top of the list, e.g.
default.aspx
Default.asp
Default.htm
...
And I am still getting the same problem.
Update:
The event handler is only getting fired once because it is resulting in a NullReferenceException. I've done some additional reading and I know ASP.NET triggers these events for every request, even for CSS or JavaScript files. Additionally, the session object is not loaded for static files because there is not code that accesses the session, thus no need to load the object. Even so, the very first request is the request for the web page, which will need the session, and the session is null.
#DmytroShevchenko asked:
First add a guard check if (HttpContext.Current.Session != null) so that there is no NullReferenceException thrown. Then try to see, maybe the event will be fired a second time, with a session available.
Modified code:
void Application_AcquireRequestState(object sender, EventArgs e)
{
if (HttpContext.Current.Session != null)
{
HttpContext.Current.Session["key"] = "value";
}
}
I set a break point at the if statement. I saw this event fire 4 times:
session is null
session is null
session not null
session is null
When continuing to step through the code each time, only when it started executing Default.aspx and its code-behind did I have a session available. I actually had the web page open in Firefox and was monitoring the network requests. The first request was for http://localhost/Foo/.
Next I set a breakpoint in Application_BeginRequest as well and got the following events:
BeginRequest
AcquireRequestState
BeginRequest
AcquireRequestState
BeginRequest
AcquireRequestState (session is not null)
Execute Default.aspx (/Foo returns a response to the browser)
BeginRequest
AcquireRequestState (session is null again)
At #9 the AJAX request in the browser to http://localhost:54859/8fad4e71e57a4caebe1c6ed7af6f583a/arterySignalR/poll?transport=longPolling&connectionToken=...&messageId=...&requestUrl=http%3A%2F%2Flocalhost%2FFoo%2F&browserName=Firefox&userAgent=Mozilla%2F5.0+(Windows+NT+6.1%3B+WOW64%3B+rv%3A41.0)+Gecko%2F20100101+Firefox%2F41.0&tid=4&_=1445346977956 is hanging waiting for a response.
I found a discussion about the differences between serving a page by its explicit URL and serving a default document.
With MVC and WebAPI, a new HttpModule was introduced: ExtensionlessUrlHandler. I believe that your event firing multiple times (and only once with session being available) may be caused by this module or other (re)routing logic of ASP.NET that actually redirects ASP.NET to handle Default.aspx.
Also, as you yourself mentioned, these events can be triggered for static file requests.
The bottom line is, you should not rely on session being available every time your event is fired. But it is safe to assume that you can access session at least once when serving an ASP.NET page. Hence, this is how your code should look like:
void Application_AcquireRequestState(object sender, EventArgs e)
{
if (HttpContext.Current.Session != null)
{
HttpContext.Current.Session["key"] = "value";
}
}
What is happening is that certain events that occur prior to transferring the request to the page, trigger this event. Similarly, this event can be raised by other than ASPX pages. I think you need to do a few things:
set AutoEventWireUp to false in your page's code (in default.aspx). It seems odd and unrelated, but apparently this can resolve your issue.
check for null. Really. Because from all events, you are only interested in those events that originated from an ASPX page (or similar) that actually have a session state. Since every true request from a user always creates a session, you can simply filter for these without worrying that you miss certain events. As you have seen, at every cycle, there is always at least one event hit that has a set Session.
use PostAcquireRequestState, it is the more natural thing to use (or use PreRequestHandlerExecute), because on that event, all state is guaranteed to be set and filled.
I think your request url is not contain ".aspx", right?
The IIS7+ version has the config whitch will not use the "SessionStateModule" when it think the request handler is not managedHandler
So the solution is easy
Find your web.config, then add the property
<modules runAllManagedModulesForAllRequests="true">
....
</modules>
runAllManagedModulesForAllRequests="true" tell asp.net use all modules anyway
hope helpfull
When the resource has compilation error then the session will be null even in Application_PostAcquireRequestState

How to get the previous url in C#?

How to get the previous url in a MasterPage in C# ?
I'm trying to find the page which is redirected from.
Thanks in advance.
You can get information of the previous url with the UrlReferrer property. This works in MVC and Web forms.
Request.UrlReferrer.AbsoluteUri
Note that in the first page the property Request.UrlReferrer will be null. Also, it will be null if a redirection occurs (e.g. when a user logs into the web page).
This property is based on the HTTP_REFERER variable, so you could use this one instead.
Request.ServerVariables["HTTP_REFERER"]
Since the HTTP_REFERER is a variable sent by the client it might be altered or removed by the request. Also, the variable is not set when the referre url starts with https.
This article mentions a few points why the Request.UrlReferrer can be null.
Usually you use a query string parameter to achieve this: current?previousUrl=/some/11.
This will allow you to access this value from the server-side code using Context.Request.QueryString["previousUrl"] in your master page code-behind.
string urlName = Request.UrlReferrer.ToString();

Accessing https page

I am currently adding an aspx page to my web site (.net) where my clients can insert credit card details.
I would like to give access for that page from several pages only (lets call them a.aspx and b.aspx) and if someone tries to access this page from c.aspx he won't be able to do so.
Is there a way to limit the redirect to a page for few pages only?
I've tried to check at the page event what is the source of the call, with the "sender" object, however I am not sure it the right way to go.
Hope the question is clear enough.
What you need to know to do this is the referer.
The referer is, briefly, the page that brought you to the page you are currently at.
I believe this should get the referrer for ASP.net
Request.Server["HTTP_REFERER"]
Then you can just check and see if the referer matches your desired origins. However, I'm not sure about the ease/prevalence of referer spoofing, or if it even exists.
Yes there is - have a look at the HttpWebRequest.Referer property.
Using this you can see from which page the request to c.aspx is made - if it's not a.aspx or b.aspx you can redirect the user away.
As menitoned previously you need to check the current UrlReferrer, here is an example in vb.net
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim bRedirect As Boolean = True
Try
If Not IsNothing(Page.Request.UrlReferrer) Then
Dim sReferer As String = Page.Request.UrlReferrer.ToString()
If sReferer.Contains("/a.aspx") Or sReferer.Contains("/b.aspx") Then
bRedirect = False
End If
Catch ex As Exception
' Raise exception, decide whether or not to redirect
End Try
If bRedirect Then
Response.Redirect("~/x.aspx", True)
End If
End Sub

custom httphandler in asp.net cannot get request querystring?

I've been trying to get this to work. It's basically a way to have certain MVC pages work within a webforms cms (umbraco)
Someone tried it before me and had issues with MVC2.0 (see here), I have read the post, did what was announced there, but with or without that code, I seem to get stuck on a different matter.
It seems like, if I call an url, it fires the handler, but fails to request the querystring passed, the variable originalPath is always empty,
for example I call this url: http://localhost:8080/mvc.ashx?mvcRoute=/home/RSVPForm
the handler is supposed to get the mvcRoute but it is always empty. Thus gets rewritten to a simple / and then returns resource cannot be found error.
Here is the code I use now:
public void ProcessRequest(HttpContext httpContext)
{
string originalPath = httpContext.Request.Path;
string newPath = httpContext.Request.QueryString["mvcRoute"];
if (string.IsNullOrEmpty(newPath))
newPath = "/";
HttpContext.Current.RewritePath(newPath, false);
IHttpHandler ih = (IHttpHandler)new MvcHttpHandler();
ih.ProcessRequest(httpContext);
HttpContext.Current.RewritePath(originalPath, false);
}
I would like some new input on this as I'm staring myself blind on such a simple issue, while I thought I would have more problems with mvc itself.
have no time to investigate, but after copying the site over to different locations, using numerous web.config changes (unrelated to this error but was figuring other things out) this error seems to have solved itself. so its no longer an issue, however i have no clue as to what exactly made this to work again.
on a side note
ih.ProcessRequest(httpContext);
should have been,
ih.ProcessRequest(HttpContext.Current);

Unhandled Exception CachedRawResponse asp.net

Unable to cast object of type 'System.Web.Caching.CachedRawResponse' to type 'System.Web.Caching.CachedVary'.
I'm getting this on an AJAX call to an aspx page, and can find no information about it in webland. CachedRawResponse isn't even on MSDN. Does anyone know anything about it, or maybe point me in the right direction?
We recently had the same problem, and it turned out (in our case) that the page output cache module is rather sensitive to how you set your Response.Cache.VaryByXyz properties. We used code like the following in our HTTP compression module:
if (IsBrowserSupported(userAgent))
{
Response.Cache.VaryByHeaders["Accept-Encoding"] = true;
...
}
Unfortunately, this causes ASP.NET to throw a fit when the page is cached after a call by a non-supported browser, and subsequently requested from the cache by a supported browser.
Not setting any VaryByXyz causes a CachedRawResponse to be stored in the ASP.NET output cache, but if you do set any VaryByXyz during your request, ASP.NET expects a CachedVary at that location. And instead of checking whether the cached page is of the right type, the framework just casts, resulting in an InvalidCastException.
Moral of the story: always set the VaryByXyz consistently, regardless of the request headers or other non-request-related variables. In our case, placing the VaryByHeaders outside of the if solved the error.

Categories