back

Asp.Net Page Objects - Page Execution - Url Rewriting

Various url for this page:
/ASP.NET_Memento/Page_Objectswith query
/ASP.NET_Memento/Page_Objects/RED/green/bluewith query
/ASP.NET_Memento/Page_Objects/With_Forms_Authenticationwith query
/ASP.NET_Memento/Page_Objects/With_Forms_Authentication/yellowwith query
These urls are obtained by means of url rewriting.
The urls that contain "With_Forms_Authentication" use forms authentication.
Url rewriting:
This page uses url rewriting from IIS url rewrite module 2.0 External Link (iis.net).
IIS url rewrite module conditions:
A condition tests a server variable value.
IIS url rewrite module reference is here External Link (iis.net). This document explains server variables use, but does not list which one can be tested, and what do these variables contain.
Added HTTP header:
The url rewrite module adds the "X-Original-URL" http header and its value contains the original url. There are others ways to get the original url. See below Requested Url.
Publishing the same aspx page with and without forms authentication:
To show what differs when forms authentication is used, this page can be obtained either by means of an anonymous login or by means of forms authentication. This behavior is achieved this way:
Depending on the url, this web page is either generated by "Page_Objects" or by "With_Forms_Authentication" asp.net application. Page_Objects application uses anonymous login while With_Forms_Authentication application uses forms authentication.
With_Forms_Authentication application uses the same aspx page as Page_Objects application. This page is located in Page_Objects application folder. With_Forms_Authentication application defines a virtual directory named "VirtualDir". This virtual directory points to the aspx page folder. With_Forms_Authentication application url rewriting prepends "VirtualDir" to the rewritten path.
Removing aspx page extension on forms:
Read this about forms, aspx pages extension, and url rewriting.
This page code sets Form.Action property to prevent page extension to appear when posted.
Aspx page name:
This aspx page name ("HttpRequest from α to ω.aspx") contains spaces and characters from a non English charset. This shows what properties contain an (Unicode) aspx page name, and which one contains an url encoded aspx page name.
Url encoding:
You can get a Windows tool for RFC 3986 url encoding/decoding here. This software also gives details about this encoding standard.
Query string and url encoding:
Recent versions of IIS need urls to be encoded following current standard: RFC 3986 from 2005. But .Net originates from 2002. Current result is a mix of encoding standards.
Action Result
Page.ClientQueryString Decoded, then encoded Wrong
Page.Request.QueryString.ToString() Decoded, then encoded Wrong
Page.Request.QueryString.AllKeys
Page.Request.QueryString[0]
Page.Request.QueryString["Alice est"]
Decoded OK
Page.Request.Url.ToString() Decoded OK
Page.Request.Params["Alice est"] Decoded OK
Page.Request.UrlReferrer Decoded OK
Server.UrlDecode Decoded OK
Server.UrlEncode Encoded OK, except for space character
The links "with query" above add the following query: "Alice%20est=Emerveill%C3%A9e", which is url encoding for "Alice est=Emerveillée" following RFC 3986.
Note that when an url encoded character is not understood, it is decoded to the "Unicode replacement character". This character means "character that cannot be represented". It is displayed as a question mark (�) and its code is 65533 (hexa: FFFD).
Form tag rendering:
Form ID default value is changed for "CanonicalForm" to show where this value appears on properties.
HttpRequest.InputStream gives access to the raw request (request without http headers).
Form and XHTML 1.0 Strict:
Recent .NET Framework versions generate XHTML 1.0 Strict conform code. The form tag does not contain any more a name attribute, and the viewstate hidden input tag is enclosed into a div tag. If not, make sure web.config does not contain "<pages controlRenderingCompatibilityVersion="3.5" ... />".
But .NET code generation depends on browser identification. The W3C validator sends a user agent header like "W3C_Validator/1.3 http://validator.w3.org/services". Asp.Net does not identify this client as XHTML 1.0 Strict compatible, so it renders code for an older standard. For this reason, the W3C validator does not validate a XHTML 1.0 Strict page when "validated by URI", but validates by "Direct Input".
If you need to prove that your code is XHTML 1.0 Strict valid when "validated by URI", you have to create a browser definition External Link (MSDN) for the W3C validator user agent. This can be done this way, at application level:
  • In Visual Studio, right-click on the Asp.Net project, then click on Add / Add the ASP.NET folder / App_Browsers
  • In a new .browser file located into the App_Browsers new folder, just place this code:
    <browsers>
    <browser id="W3CValidator" parentID="default">
    <identification>
    <userAgent match="^W3C_Validator" />
    </identification>
    <capabilities>
    <capability name="tagWriter" value="System.Web.UI.HtmlTextWriter" />
    </capabilities>
    </browser>
    </browsers>
Posting a form:
This page form tag bellow has a yellow border.
Html tags
Asp.Net controls
You can choose between two form contents:
This form contains Html input tags, and the same tags rendered by Asp.Net controls.
Buttons text uses characters from several alphabets so you can see how this text is encoded when posted.
A browser posts HTML input tag value if it has a name attribute.
  • An Asp.Net control forces the rendered HTML tag name attribute to its ID value.
  • HTML tags created by dropping an HTML tag from the Visual Studio toolbox have no name attribute. If you want to use one in a form, you have to add it a name attribute manually.
The input tags above display their name attribute on a tooltip.
Asp.Net sets the form tag enctype attribute this way:
  • The page contains no file upload tag:
    enctype attribute is not specified, meaning the application/x-www-form-urlencoded default value is used.
  • The page contains a file upload tag (<input type="file">):
    enctype attribute value is set to multipart/form-data
This attribute has this effect on the browser on a POST request:
  • The browser sends a Content-Type HTTP header with either application/x-www-form-urlencoded or multipart/form-data; boundary=... value.
  • Posted data uses the corresponding format.
To test how a browser posts a form, and how asp.net server code gets this data, enter text, select a file to post, click on a button, and inspect Page.Request.Form, Page.Request.Files, Page.Request.Params, and Page.Request.InputStream sections. This will show you:
  • How to read user input on html tags.
  • How to read user input on Asp.Net controls, early on page life cycle, and without using controls events mechanism.
  • What is the difference between form url encoded and multipart formats
When posting a file, you are recommended to use a very small text file so you can see how its data is transmitted.
Request filtering is set for this page to allow only small files posting (up to 1 kB is ok).
If you try to post a too large data, you will receive a 404 error page.
If you want to test how a binary file is transmitted, you can get a file containing the 256 bytes values here: /ASP.NET_Memento/256.bin.
Event validation
EventValidation is disabled on this page.
Session:
If the server receives no session cookie, it sends a session cookie containing the session ID.
To make sure this cookie is sent even if you do not store values into the session state, use this code in the application global.asax file:
protected void Session_Start(object sender, EventArgs e)
{
if (this.Session.IsNewSession)
{
this.Session["a"] = true;
this.Session.Clear();
}
}
Remark: the session cookie named ASP.NET_SessionId is always present in the Request.Cookies collection, even if the server did not receive a session cookie.
To know whether session cookie was received, parse Request.Headers["Cookie"] potential value.
Session.Count tests if the session state contains data.
The cookie test page allows you to observe Asp.Net session state management.
ViewState:
ViewState is disabled on this page. For more about ViewState, read this.
Forms authentication
Some Forms Authentication traps are explained here.
Physical paths
asp.net application physical absolute path: Request.PhysicalApplicationPath and Request.Params["APPL_PHYSICAL_PATH"].
aspx file physical absolute path: Request.PhysicalPath and Request.Params["PATH_TRANSLATED"].
Server.MapPath method can also be used to get some physical paths.
IIS Site ID
IIS assigns each virtual site an integer ID, visible on IIS manager and in C:\Windows\System32\inetsrv\config\applicationHost.config file.
This number can be obtained from Request.Params["INSTANCE_ID"].
It also appears on these values: Request.Params["INSTANCE_META_PATH"], Request.Params["APPL_MD_PATH"], HttpRuntime.AppDomainAppId, and HttpRuntime.AppDomainId.
Accessing important objects out of a page context
The following data can be obtained from a Page code context. But you may also need to access it out of this context. This is how to get a reference on the main Asp.Net objects out of a page code:
context System.Web.HttpContext context = System.Web.HttpContext.Current;
request System.Web.HttpRequest request = System.Web.HttpContext.Current.Request;
response System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
session System.Web.SessionState.HttpSessionState session = System.Web.HttpContext.Current.Session;
HttpServerUtility System.Web.HttpServerUtility server = System.Web.HttpContext.Current.Server;
Url parts
Some url parts below are emphasized this way:
Host, Asp.Net applications path, Aspx page name, url encoded Aspx page name, Query
Some Page propertiesSystem.Web.UI.Page
AppRelativeTemplateSourceDirectory~/
AppRelativeVirtualPath~/HttpRequest from α to ω.aspx
ClientID__Page
ClientIDMode.ToString()Inherit
ClientQueryString
ClientTarget
CultureEnglish (United States)
UICultureEnglish (United States)
IsPostBackFalse
MaintainScrollPositionOnPostBackFalse
UniqueID__Page
User.Identity.Name
ViewStateUserKeynull
Requested Url
Page.Request.RawUrl/ASP.NET_Memento/Page_Objects/
Page.Request.Headers["X-Original-URL"]/ASP.NET_Memento/Page_Objects/
Page.Request.Params["HTTP_X_ORIGINAL_URL"]/ASP.NET_Memento/Page_Objects/
Page.Request.ServerVariables["HTTP_X_ORIGINAL_URL"]/ASP.NET_Memento/Page_Objects/
Page.Request.Url (rewritten)System.Uri
ToString()http://www.ristaino.net/Asp.Net_Memento/Page_Objects/HttpRequest from α to ω.aspx
AbsolutePath/Asp.Net_Memento/Page_Objects/HttpRequest%20from%20%CE%B1%20to%20%CF%89.aspx
AbsoluteUrihttp://www.ristaino.net/Asp.Net_Memento/Page_Objects/HttpRequest%20from%20%CE%B1%20to%20%CF%89.aspx
Authoritywww.ristaino.net
DnsSafeHostwww.ristaino.net
Fragment
Hostwww.ristaino.net
HostNameType.ToString()Dns
LocalPath/Asp.Net_Memento/Page_Objects/HttpRequest from α to ω.aspx
OriginalStringhttp://www.ristaino.net:80/Asp.Net_Memento/Page_Objects/HttpRequest%20from%20%CE%B1%20to%20%CF%89.aspx
PathAndQuery/Asp.Net_Memento/Page_Objects/HttpRequest%20from%20%CE%B1%20to%20%CF%89.aspx
GetLeftPart(UriPartial.Scheme)http://
GetLeftPart(UriPartial.Authority)http://www.ristaino.net
GetLeftPart(UriPartial.Path)http://www.ristaino.net/Asp.Net_Memento/Page_Objects/HttpRequest%20from%20%CE%B1%20to%20%CF%89.aspx
GetLeftPart(UriPartial.Query)http://www.ristaino.net/Asp.Net_Memento/Page_Objects/HttpRequest%20from%20%CE%B1%20to%20%CF%89.aspx
Port80
Query
Schemehttp
Segments[0] = /
[1] = Asp.Net_Memento/
[2] = Page_Objects/
[3] = HttpRequest%20from%20%CE%B1%20to%20%CF%89.aspx
UserInfo
IsAbsoluteUriTrue
IsDefaultPortTrue
IsFileFalse
IsLoopbackFalse
IsUncFalse
UserEscapedFalse
Page.Request.QueryStringSystem.Collections.Specialized.NameValueCollection
ToString()
Count0
Decoding query string using Server class
Server.UrlDecode(Request.Url.Query)
Page.Request.HeadersSystem.Collections.Specialized.NameValueCollection
Count7
["Connection"]Keep-Alive
["Content-Length"]0
["Accept"]text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
["Accept-Encoding"]gzip
["Host"]www.ristaino.net
["User-Agent"]CCBot/2.0 (https://commoncrawl.org/faq/)
["X-Original-URL"]/ASP.NET_Memento/Page_Objects/
Page.Request.CookiesSystem.Web.HttpCookieCollection : NameObjectCollectionBase
Count1
["ASP.NET_SessionId"].Value = 3l2n1rjvr5pw2jbnm3oclrll
Some Page.Request.Browser propertiesSystem.Web.HttpBrowserCapabilities
BrowserUnknown
Iddefault
MobileDeviceManufacturerUnknown
MobileDeviceModelUnknown
PlatformUnknown
Version0.0
TypeUnknown
Page.SessionSystem.Web.SessionState.HttpSessionState
.SessionID3l2n1rjvr5pw2jbnm3oclrll
Page.FormSystem.Web.UI.HtmlControls.HtmlForm
Target
TagNameform
NameCanonicalForm
Methodpost
IDCanonicalForm
Enctype
Action (modified by this page code: read above)http://www.ristaino.net/ASP.NET_Memento/Page_Objects/
Page.Request.FormSystem.Collections.Specialized.NameValueCollection
Count0
Page.Request.FilesSystem.Web.HttpFileCollection
Count0
Page.Request.InputStreamSystem.IO.Stream
data read from:no content
Others Page.Request properties
AcceptTypes[0] = text/html
[1] = application/xhtml+xml
[2] = application/xml;q=0.9
[3] = */*;q=0.8
AnonymousIDnull
ApplicationPath/Asp.Net_Memento/Page_Objects
AppRelativeCurrentExecutionFilePath~/HttpRequest from α to ω.aspx
ContentEncoding.EncodingNameUnicode (UTF-8)
ContentLength0
ContentType
CurrentExecutionFilePath/Asp.Net_Memento/Page_Objects/HttpRequest from α to ω.aspx
FilePath/Asp.Net_Memento/Page_Objects/HttpRequest from α to ω.aspx
HttpMethodGET
IsAuthenticatedFalse
IsLocalFalse
IsSecureConnectionFalse
Path/Asp.Net_Memento/Page_Objects/HttpRequest from α to ω.aspx
PathInfo
PhysicalApplicationPath< Absolute physical path to the asp.net application folder ended by "\" >
PhysicalPath< Absolute physical path to the aspx file folder >\HttpRequest from α to ω.aspx
ReadEntityBodyModeClassic
RequestTypeGET
TotalBytes0
UrlReferrernull
UserAgentCCBot/2.0 (https://commoncrawl.org/faq/)
UserHostAddress54.167.15.6
UserHostName54.167.15.6
UserLanguagesnull
Page.Request.Params and
Page.Request.ServerVariables
System.Collections.Specialized.NameValueCollection
XALL_HTTP
HTTP_CONNECTION:Keep-Alive
HTTP_CONTENT_LENGTH:0
HTTP_ACCEPT:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
HTTP_ACCEPT_ENCODING:gzip
HTTP_HOST:www.ristaino.net
HTTP_USER_AGENT:CCBot/2.0 (https://commoncrawl.org/faq/)
HTTP_X_ORIGINAL_URL:/ASP.NET_Memento/Page_Objects/
XALL_RAW
Connection: Keep-Alive
Content-Length: 0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip
Host: www.ristaino.net
User-Agent: CCBot/2.0 (https://commoncrawl.org/faq/)
X-Original-URL: /ASP.NET_Memento/Page_Objects/
XAPPL_MD_PATH
/LM/W3SVC/2/ROOT/Asp.Net_Memento/Page_Objects
XAPPL_PHYSICAL_PATH
< Absolute physical path to the asp.net application folder ended by "\" >
 ASP.NET_SessionId
exists only in Request.Params
3l2n1rjvr5pw2jbnm3oclrll
 AUTH_PASSWORD
 AUTH_TYPE
 AUTH_USER
XCERT_COOKIE
XCERT_FLAGS
XCERT_ISSUER
XCERT_KEYSIZE
XCERT_SECRETKEYSIZE
XCERT_SERIALNUMBER
XCERT_SERVER_ISSUER
XCERT_SERVER_SUBJECT
XCERT_SUBJECT
XCONTENT_LENGTH
0
XCONTENT_TYPE
XGATEWAY_INTERFACE
CGI/1.1
XHTTP_ACCEPT
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
XHTTP_ACCEPT_ENCODING
gzip
XHTTP_CONNECTION
Keep-Alive
XHTTP_CONTENT_LENGTH
0
XHTTP_HOST
www.ristaino.net
XHTTP_USER_AGENT
CCBot/2.0 (https://commoncrawl.org/faq/)
 HTTP_X_ORIGINAL_URL
/ASP.NET_Memento/Page_Objects/
XHTTPS
off
XHTTPS_KEYSIZE
XHTTPS_SECRETKEYSIZE
XHTTPS_SERVER_ISSUER
XHTTPS_SERVER_SUBJECT
XINSTANCE_ID
2
XINSTANCE_META_PATH
/LM/W3SVC/2
XLOCAL_ADDR
178.170.124.46
 LOGON_USER
XPATH_INFO
/Asp.Net_Memento/Page_Objects/HttpRequest from α to ω.aspx
XPATH_TRANSLATED
< Absolute physical path to the aspx file folder >\HttpRequest from α to ω.aspx
XQUERY_STRING
XREMOTE_ADDR
54.167.15.6
XREMOTE_HOST
54.167.15.6
XREMOTE_PORT
56604
XREMOTE_USER
XREQUEST_METHOD
GET
XSCRIPT_NAME
/Asp.Net_Memento/Page_Objects/HttpRequest from α to ω.aspx
XSERVER_NAME
www.ristaino.net
XSERVER_PORT
80
XSERVER_PORT_SECURE
0
XSERVER_PROTOCOL
HTTP/1.1
XSERVER_SOFTWARE
Microsoft-IIS/8.5
XURL
/Asp.Net_Memento/Page_Objects/HttpRequest from α to ω.aspx
Page.ContextSystem.Web.HttpContext
Cache.Count0
TimestampSunday, December 16, 2018 10:16:04 PM
User.Identity.Name
User identity obtained from
Request.LogonUserIdentity
System.Security.Principal.WindowsIdentity
NameNT AUTHORITY\IUSR
AuthenticationType
IsAnonymousFalse
IsAuthenticatedFalse
IsGuestFalse
IsSystemFalse
ImpersonationLevelImpersonation
User.ValueS-1-5-17
User.IsAccountSid()False
User groups obtained from:
Request.LogonUserIdentity.Groups
System.Security.Principal.IdentityReferenceCollection
S-1-1-0Everyone
S-1-2-0LOCAL
S-1-2-1CONSOLE LOGON
S-1-5-11NT AUTHORITY\Authenticated Users
S-1-5-15NT AUTHORITY\This Organization
S-1-5-32-545BUILTIN\Users
Impersonated user identity obtained from:
WindowsIdentity.GetCurrent()
System.Security.Principal.WindowsIdentity
Name< machine name >\< application pool name >
AuthenticationTypeNegotiate
IsAnonymousFalse
IsAuthenticatedTrue
IsGuestFalse
IsSystemFalse
ImpersonationLevelNone
User.ValueS-1-5-82-< SHA1 hash code for the application pool name >
User.IsAccountSid()False
Impersonated user groups obtained from:
WindowsIdentity.GetCurrent().Groups
System.Security.Principal.IdentityReferenceCollection
S-1-1-0Everyone
S-1-2-0LOCAL
S-1-2-1CONSOLE LOGON
S-1-5-6NT AUTHORITY\SERVICE
S-1-5-11NT AUTHORITY\Authenticated Users
S-1-5-15NT AUTHORITY\This Organization
S-1-5-32-545BUILTIN\Users
S-1-5-32-568BUILTIN\IIS_IUSRS
S-1-5-82-0
Go to toptop