【问题标题】:Postback doesn't work with aspx page as Default Document回发不适用于 aspx 页面作为默认文档
【发布时间】:2011-11-05 21:36:02
【问题描述】:

如果我浏览到http://localhost/edumatic3/trunk/login/accesscode/Default.aspx,我的回发工作。但是,如果我浏览到 http://localhost/edumatic3/trunk/login/accesscode/(将 Default.aspx 定义为默认文档),我的回发将不起作用。

有没有办法让它工作?或者我应该删除默认文档并强制用户浏览到http://localhost/edumatic3/trunk/login/accesscode/default.aspx

更新:

代码(部分):

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

后面的代码(部分):

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)
{
 ....

当我点击ImageButton时,Page_Load被触发,IsPostBack为假...正常情况下应该为真。根本没有触发 ContinueImageButton_Click(...)。

在 HTML 中(部分):

<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请求:

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...

【问题讨论】:

  • 您能否提供您的 default.aspx 文件的代码,回发不起作用的事实是该文件正在使用 head 请求而不是 get 或 post 请求进行重定向。这就是为什么它不起作用。
  • 完成。如果我查看 Charles(http 嗅探器),我可以看到正在向服务器发送 POST。
  • 当你说你的回发“不起作用”时,你到底是什么意思?您可能想在代码隐藏中放置一些断点并使用调试器运行以查看到底发生了什么。
  • 如果您在页面未按预期运行时遇到问题,您可能会在页面中包含您的代码隐藏。
  • 只是为了看看它是否有所作为,把 CausesValidation="false" 放在你的按钮上,看看它是否改变了什么。

标签: .net asp.net iis


【解决方案1】:

考虑使用通过 web.config 完成的 URL 映射。这样您就可以避免在您的应用程序中添加额外的代码,让 IIS 为您工作。

<system.web>
    <urlMappings>
        <add url="~/login" mappedUrl="~/login/default.aspx" />
        <add url="~/login/" mappedUrl="~/login/default.aspx" />
        <add url="~/this-folder-does-not-exist" mappedUrl="~/login/default.aspx" />
        <add url="~/this-folder-does-not-exist/" mappedUrl="~/login/default.aspx" />
    </urlMappings>
</system.web>

确保包含带有和不带有结尾斜杠的 URL 的两个版本。

当您需要快速更改并且不想修改源代码时,您还可以从虚拟文件夹创建重定向(如上所示的“this-folder-does-not-exist”示例)。

【讨论】:

  • 不,这不起作用。看起来像
    的元素似乎是问题所在 - 所以它甚至不会尝试正确回发。不过这个主意不错。
【解决方案2】:

我想我会尝试重现这个,你说的完全正确。它在没有default.aspx 的情况下中断,您提供了一个非常简单的示例。查看 HTML,原因很清楚。因为action属性是空的。

快速搜索发现了这一点,ASP.NET 4 Breaking Changes(请参阅在 IIS 7 或 IIS 7.5 集成模式下的默认文档中可能不会引发事件处理程序)。

ASP.NET 4 现在呈现 HTML 表单元素的 action 属性值 当向无扩展名 URL 发出请求时作为空字符串 有一个映射到它的默认文档。例如,在早期版本中 在 ASP.NET 中,对 http://contoso.com 的请求将导致请求 到 Default.aspx。在该文档中,开始表单标签将是 如下例所示:

<form action="Default.aspx" />

在 ASP.NET 4 中,对 http://contoso.com 的请求也会导致 请求 Default.aspx。但是,ASP.NET 现在呈现 HTML 开头 form 标签如下例所示:

<form action="" />

action 属性呈现方式的差异可能导致 IIS 和 ASP.NET 如何处理表单发布的细微变化。 当 action 属性为空字符串时,IIS DefaultDocumentModule 对象将创建一个子请求以 默认.aspx。在大多数情况下,这个子请求是透明的 到应用程序代码,Default.aspx页面正常运行。

但是,托管代码与 IIS 7 或 IIS 之间的潜在交互 7.5 集成模式会导致托管 .aspx 页面停止工作 在子请求期间正确。

我已经创建了这两个解决问题的修复程序,请使用任何一个。

1) 将此代码添加到 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) 创建表单控件适配器

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);
        }
    }
}

通过在 App_Browsers\Default.browsers 中创建此文件来注册它

<browsers>
    <browser refID="Default">
       <controlAdapters>
          <adapter controlType="System.Web.UI.HtmlControls.HtmlForm"
                            adapterType="TheCodeKing.Web.FormControlAdapter" />
       </controlAdapters>
    </browser>
</browsers>

【讨论】:

  • 就我而言,问题出在 FluorineFx HTTP 模块(.NET Amf 远程网关)。如果我在 web.config 中将 preCondition="managedHandler" 添加到模块的配置中,一切正常。然而,FluorineFx 也处理静态内容,所以如果你想让它继续工作,最好手动设置 Form 上的 Action 属性。
  • 这很好,但是有什么方法可以配置 IIS 来修复它,而不必更改代码?对我来说闻起来像是 IIS 错误,或者只是 MS 的糟糕设计。
  • 另外,如果您不在母版页级别使用表单,并且仅在几个页面上使用它,包括默认页面,您可以设置操作
  • 如果包装表单标签在 Site.master 中但每个子页面都处理自己的请求怎么办?当我在 Users.aspx 页面上时,我不想向 Default.aspx 发送请求...
【解决方案3】:

另一个选项是在呈现页面之前检查表单操作是否为空。这对我有用:

    public void Page_PreRender(object sender, EventArgs e)
    {
        if (string.IsNullOrEmpty(this.Page.Form.Action))
            this.Page.Form.Action = "Default.aspx";
    }

【讨论】:

  • 如果使用上述方法,请不要忘记附加查询字符串,否则 returnurl 之类的内容将不起作用。 this.Page.Form.Action = "default.aspx" + Page.Request.QueryString;
  • 我之前的评论缺少 ?对于查询字符串,所以:this.Page.Form.Action = "default.aspx?" + Page.Request.QueryString.ToString();
  • 如果指定了 QueryString - 那么 Form.Action 不会是 NullorEmpty
  • Private Sub Page_PreRender(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.PreRender If String.IsNullOrEmpty(Page.Form.Action) OrElse Page.Form.Action.StartsWith( "?") Then If Page.Request.QueryString.Count = 0 Then Page.Form.Action = "Default.aspx" Else Page.Form.Action = "Default.aspx?" & Page.Request.QueryString.ToString() End If End If End Sub
  • 如果您使用 FriendlyUrls,这会破坏其他页面,例如 /search(工作正常),所以我添加了第二个测试以确保它仅在默认页面上: if (string.IsNullOrEmpty( this.Page.Form.Action) && Request.Url.AbsolutePath == "/default.aspx") this.Page.Form.Action = "Default.aspx";
【解决方案4】:

如果您的表单处理器操作不在根目录中,您应该能够使用绝对路径而不使用文件名。

<form action='/form/processor/' method=post id='myform'>

在 .NET 2.0 中测试

该问题出现在空白操作路径中,但在路径条目中可以正常工作。

【讨论】:

    【解决方案5】:

    当我将我的 web 项目从 VS 2005 (.Net 2.5) 升级到 VS2010 (.Net 4.0) 时,VS2010 将以下内容插入到我的 web.config 中:

    <system.webServer>
      <defaultDocument>
            <files>
              <add value="mydefaultpage.aspx" />
            </files>
        </defaultDocument>
    </system.webServer>
    

    当我导航到“http://myserver/mywebsite”(以前可以在 .Net 2.5 下进行)时,我得到了

    “HTTP 错误 500.19 - 内部服务器错误 “请求的页面无法访问,因为该页面的相关配置数据无效。” (它显示了“defaultDocument”节点。)

    但是,我可以在 web.config 中非常简单地解决问题,只需在默认网页值的开头插入“/”,如下所示:

    <system.webServer>
      <defaultDocument>
            <files>
              <add value="/mydefaultpage.aspx" />
            </files>
        </defaultDocument>
    </system.webServer>
    

    我不需要做其他受访者建议的任何其他事情。

    这样做有什么意想不到的后果或陷阱吗?

    【讨论】:

      【解决方案6】:

      我曾经遇到过类似的问题。问题是在 IIS 中默认文档配置为 default.aspx,但我的页面名称是 Default.aspx。这只是区分大小写的问题。

      【讨论】:

      • 试过了,但并没有改变什么,slfan。
      • 我也试过了——肯定不行。你有被否决的危险! ;)
      • @IanGrainger:如果是问题的原因,它会起作用,但当操作标签为空时当然不会。当我写下我的答案时,我不知道 action 标签实际上是空的。
      • @slfan:我很惊讶这无论如何都修复了 Windows 上的任何问题。我的表单操作已经是“default.aspx” - 但页面被称为 Default.aspx(默认文档规则条目也是“default.aspx”)并且它工作正常。除了它不是因为动作是空白的:)
      • 这不是 Windows 问题,问题出在我使用的库中。代码将“Default.aspx”与当前页面进行比较,比较区分大小写。
      【解决方案7】:

      您是否尝试过将图像按钮设置为使用命令事件而不是“单击”?

      我认为“可能”图片点击不会导致完整的回发,或许可以尝试如下定义:

        void ImageButton_Command(object sender, CommandEventArgs e) 
        {
           if (e.CommandName == "YourCommandName")
              //do your action
        }
      

      然后像这样定义你的按钮:

            <asp:ImageButton id="btn1" runat="server"
             ImageUrl="images/image.jpg"
             OnCommand="ImageButton_Command"
             CommandName="YourCommandName"/>
      

      我似乎记得需要这样做以允许图像按钮“提交”表单,所以我认为这会导致您所追求的回发。

      【讨论】:

        【解决方案8】:

        如果您有兴趣在您的 default.aspx 文件中添加一些额外的代码,那么您可以使用博客文章 here 中定义的类似方法;这是关于将用户重定向到相同的默认页面但具有明确的页面名称....

        //代码,复制自提到的博客

        protected void Page_Load(object sender, EventArgs e)
        {        
            string defaultPage = "default.aspx";
            string rawUrl = Request.RawUrl; //get current url
        
            //if current url doesn't contains default page name then add
            //default page name, and append query string as it is, if any
            if (rawUrl.ToLower().IndexOf(defaultPage) < 0)
            {
                string newUrl;
                if (rawUrl.IndexOf("?") >= 0)
                {
                    // URL contains query string
                    string[] urlParts = rawUrl.Split("?".ToCharArray(), 2);
        
                    newUrl = urlParts[0] + defaultPage + "?" + urlParts[1];
                }
                else
                {
                    newUrl = (rawUrl.EndsWith("/")) ? rawUrl + defaultPage : rawUrl + "/" + defaultPage;
                }
        
                Response.Redirect(newUrl);
            }
        }
        

        【讨论】:

        • Bravo 这似乎是解决方案,您可能还想将代码粘贴到您的答案中,以使其比仅提供链接更完整。
        • 这是一个很好的解决方法,但是您看到的不是 IMO 的正常行为,它应该可以正常工作。您的环境混乱或有其他因素在起作用。
        猜你喜欢
        • 2015-04-13
        • 2021-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-16
        • 1970-01-01
        • 2015-02-19
        相关资源
        最近更新 更多