Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postback doesn't work with aspx page as Default Document

Tags:

.net

asp.net

iis

If I browse to http://localhost/edumatic3/trunk/login/accesscode/Default.aspx, my postback works. However, if I browse to http://localhost/edumatic3/trunk/login/accesscode/ (with Default.aspx defined as default document), my postback doesn't work.

Is there a way to make this work? Or should I remove the default document and force users to browse to http://localhost/edumatic3/trunk/login/accesscode/default.aspx?

UPDATE:

Code (part):

<div id="continueDiv">         <asp:ImageButton ID="continueImageButton"                  runat="server" ValidationGroup="continue"                  OnClick="ContinueImageButton_Click"                  AlternateText="<%$ Resources:login, continue_alternatetext %>"/>     </div> 

Code behind (part):

protected void Page_Load(object sender, EventArgs e) {     Log.Debug("Page_Load(...)");     Log.Debug("Page_Load(...) :: PostBack = " + IsPostBack);      if (!IsPostBack)     {         continueImageButton.ImageUrl = "~/App_Themes/" + base.Theme          + "/images/" + Resources.login.btn_continue;     } }  /// <summary> /// Continue Image Button Click Handler /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void ContinueImageButton_Click(object sender, EventArgs e) {  .... 

When I click on the ImageButton, Page_Load is triggered, and IsPostBack is false... Normally, it should be true. ContinueImageButton_Click(...) isn't triggered at all.

In HTML (part):

<input type="image" name="ctl00$ContentPlaceHolder1$continueImageButton"  id="ctl00_ContentPlaceHolder1_continueImageButton"  src="../../App_Themes/LoginTedu/images/en_continue.png" alt="Continue"  onclick="javascript:WebForm_DoPostBackWithOptions(new  WebForm_PostBackOptions(&quot;ctl00$ContentPlaceHolder1$continueImageButton&quot;,  &quot;&quot;, true, &quot;continue&quot;, &quot;&quot;, false, false))"  style="border-width:0px;"> 

Http request:

POST /edumatic3/trunk/login/accesscode/ HTTP/1.1 Host: localhost Referer: http://localhost/edumatic3/trunk/login/accesscode/ Content-Length: 1351 Cache-Control: max-age=0 Origin: http://localhost User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1     (KHTML, like Gecko)                 Chrome/13.0.782.215 Safari/535.1 Content-Type: application/x-www-form-urlencoded Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Encoding: gzip,deflate,sdch Accept-Language: nl,en-US;q=0.8,en;q=0.6,fr;q=0.4 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 ASP.NET_SessionId=33yal3buv310y2etuj33qghg; CurrenUICulture=en-us  __EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDw... 
like image 226
Lieven Cardoen Avatar asked Aug 29 '11 09:08

Lieven Cardoen


People also ask

What is PostBack method?

In web development, a postback is an HTTP POST to the same page that the form is on. In other words, the contents of the form are POSTed back to the same URL as the form. Postbacks are commonly seen in edit forms, where the user introduces information in a form and hits "save" or "submit", causing a postback.

What is Ispost back in asp net?

IsPostBack is a property of the Asp.Net page that tells whether or not the page is on its initial load or if a user has perform a button on your web page that has caused the page to post back to itself.

Why do we need PostBack?

PostBack is done if certain credentials of the page are to be checked against some sources (such as verification of username and password using database). This is something that a client machine is not able to accomplish and thus these details have to be 'posted back' to the server.


2 Answers

I thought I'd try and reproduce this, and you're absolutely right. It breaks without the default.aspx with a very simple example that you provided. Looking at the HTML, the reason is fairly clear. It's because the action attribute is empty.

A quick search reveled this, ASP.NET 4 Breaking Changes (see Event Handlers Might Not Be Not Raised in a Default Document in IIS 7 or IIS 7.5 Integrated Mode).

ASP.NET 4 now renders the HTML form element’s action attribute value as an empty string when a request is made to an extensionless URL that has a default document mapped to it. For example, in earlier releases of ASP.NET, a request to http://contoso.com would result in a request to Default.aspx. In that document, the opening form tag would be rendered as in the following example:

<form action="Default.aspx" /> 

In ASP.NET 4, a request to http://contoso.com also results in a request to Default.aspx. However, ASP.NET now renders the HTML opening form tag as in the following example:

<form action="" /> 

This difference in how the action attribute is rendered can cause subtle changes in how a form post is processed by IIS and ASP.NET. When the action attribute is an empty string, the IIS DefaultDocumentModule object will create a child request to Default.aspx. Under most conditions, this child request is transparent to application code, and the Default.aspx page runs normally.

However, a potential interaction between managed code and IIS 7 or IIS 7.5 Integrated mode can cause managed .aspx pages to stop working properly during the child request.

I've created these two fixes which resolve the issue, use either.

1) Add this code to Global.asax

void Application_BeginRequest(object sender, EventArgs e) {     var app = (HttpApplication)sender;     if (app.Context.Request.Url.LocalPath.EndsWith("/"))     {     app.Context.RewritePath(              string.Concat(app.Context.Request.Url.LocalPath, "default.aspx"));     } } 

2) Create a Forms ControlAdapter

public class FormControlAdapter : ControlAdapter {     protected override void Render(System.Web.UI.HtmlTextWriter writer)     {         base.Render(new RewriteFormHtmlTextWriter(writer));     }      public class RewriteFormHtmlTextWriter : HtmlTextWriter     {         public RewriteFormHtmlTextWriter(HtmlTextWriter writer)             : base(writer)         {             this.InnerWriter = writer.InnerWriter;         }          public override void WriteAttribute(string name, string value,                                             bool fEncode)         {             if (name.Equals("action") && string.IsNullOrEmpty(value))             {                 value = "default.aspx";             }             base.WriteAttribute(name, value, fEncode);         }     } } 

Register it by creating this file in App_Browsers\Default.browsers

<browsers>     <browser refID="Default">        <controlAdapters>           <adapter controlType="System.Web.UI.HtmlControls.HtmlForm"                             adapterType="TheCodeKing.Web.FormControlAdapter" />        </controlAdapters>     </browser> </browsers> 
like image 100
TheCodeKing Avatar answered Sep 28 '22 02:09

TheCodeKing


Another option, is to check if the form action is empty right before rendering the page. This worked for me:

    public void Page_PreRender(object sender, EventArgs e)     {         if (string.IsNullOrEmpty(this.Page.Form.Action))             this.Page.Form.Action = "Default.aspx";     } 
like image 43
Eric Avatar answered Sep 28 '22 02:09

Eric