创建和显示动态错误消息(在UpdatePanel内部不起作用)

时间:2011-07-20 18:41:44

标签: c# asp.net updatepanel htmltextwriter console.writeline

我的网络表单继承了一个名为MyPageMain的类,其内容为System.Web.UI.Page,位于App_Code文件夹中。

在这个MyPageMain类中我创建了这个方法来记录和输出异常(错误消息):

public string Error(Exception pException, string pFriendlyMessage)
{
    using (BusError erro = new BusError())
    {
        int? errorId = //HERE Routine to log the error;

        StringWriter stringWriter = new StringWriter();

        using (HtmlTextWriter writer = new HtmlTextWriter(stringWriter))
        {

            writer.AddAttribute(HtmlTextWriterAttribute.Class, "erroMain");
            writer.RenderBeginTag(HtmlTextWriterTag.Div); //<div>

            writer.RenderBeginTag(HtmlTextWriterTag.P); //<p>
            writer.Write(pFriendlyMessage);
            writer.RenderEndTag(); // </p>
            writer.RenderBeginTag(HtmlTextWriterTag.Small); 
            writer.Write("Event tracker:");
            writer.Write(errorId);
            writer.RenderEndTag(); 

            writer.RenderEndTag(); // </div>
            Console.WriteLine(stringWriter.ToString());
        }

    }
}

然后,当页面上出现异常时,我会这样称呼它:

    Protected void btnLoad_Click(object sender, EventArgs e)
    {
         LoadData();
    }        

    private void LoadData()
    {
        try
        {
             //Loading some data here.
        }
        catch (Exception ex)
        {
             Error(ex, "Unexpected error trying to load data.");
        }
    }

这是建设好的,但不起作用......我认为其中一个原因可能是整个事情都在 UpdatePanel 内。关于如何使这项工作的任何建议?

Console.Writeline适合我正在尝试做的事吗?这是否适用于UpdatePanels?

已经尝试使用Response.Write(...),但确实有效。但不在UpdatePanel

8 个答案:

答案 0 :(得分:3)

使用UpdatePanel时,您只能在从该面板触发的异步回发期间更新面板内的内容,因此您的错误消息必须显示在UpdatePanel内的某处。 (也就是说,除非您在UpdateMode="Always"之一上设置UpdatePanels,否则其内容会在每次异步和完整回发时更新。但这对您没有帮助,除非您将错误消息放入其中使用UpdatePanel拥有UpdateMode="Always",这需要您将所有UpdatePanel添加到每个页面。我知道这是您想要做什么。)

以下示例可用于在UpdatePanel的顶部添加错误消息。

您需要在Control errorParent方法中添加Error参数,以便将错误消息作为子控件添加到该父控件。

catch块中,只需传入您希望显示错误消息的容器控件。该控件必须是一个容器才能接受子控件,因此必须将其呈现为<div><span>标记,例如asp:Panelasp:UpdatePanel

在下面的示例中,您可以使用errorParent.Controls.Add(errorControl)UpdatePanel底部显示错误消息,或使用不同索引的AddAt()。请确保索引始终适用于每个页面。

接受父控件并添加新的Literal子控件:

public string Error(Exception pException, string pFriendlyMessage, Control errorParent)
{
    using (BusError erro = new BusError())
    {
        int? errorId = //HERE Routine to log the error;

        Literal errorControl = new Literal();
        errorControl.Text = String.Format("<div class=\"errorMain\"><p>{0}</p><small>Event Tracker: {1}</small></div>", pFriendlyMessage, errorId);
        errorParent.Controls.AddAt(0, errorControl);
    }
}

传递父控件:

private void LoadData()
{
    try
    {
         //Loading some data here.
    }
    catch (Exception ex)
    {
         Error(ex, "Unexpected error trying to load data.", MyUpdatePanel.ContentTemplateContainer);
    }
}

答案 1 :(得分:2)

由于您的Error方法返回字符串,您可以返回错误消息并显示它。

将Literal放在您的UpdatePanel中(可能在MasterPage中,因此您不必为所有40个或更多页面编写它)。抛出异常时,使用Error方法处理它并将返回的消息设置为Literal。

Console.WriteLine is not usable in ASP.NET。请改用Debug.WriteLine。它将写入VisualStudio中的“输出”窗口。

答案 2 :(得分:2)

许多答案围着这个问题跳舞。 Console.WriteLine是用于为控制台应用程序(命令行)输出一行文本的命令。这是一个Web应用程序。因此,您可以使用Response.Write将字符串吐出到Response流中,或者设置页面上已有的Literal控件的文本并将其设置为可见(默认隐藏)。

由于我自己完全错过了UpdatePanel细节,所以这里有一个替代解决方案来弥补它。我的示例使用隐藏的div和一些jQuery,通过使用ScriptManager控件将文本注入div之外的UpdatePanel。根据按钮的go_Click处理程序方法的条件,它将使用jQuery显示或隐藏错误消息,该消息在UpdatePanel更新时被注入页面服务器端

请注意,在使用AJAX时,使用ScriptManager的函数注册JavaScript而不是Page.ClientScript至关重要。使用后者不会将JS添加到页面中。

页面标记

<div id="errorMessagePlaceHolder" class="error" style="display:none;">
</div>
<asp:UpdatePanel ID="myPanel" runat="server">
    <ContentTemplate>
        <asp:TextBox ID="myText" runat="server" />
        <asp:Button ID="go" Text="GO" runat="server" OnClick="go_Click" />
    </ContentTemplate>
</asp:UpdatePanel>

网页代码隐藏

public partial class _Default : Page {
    protected void go_Click(object sender, EventArgs e) {
        try {
            // Do something that can throw an exception

            // Hide the error if we reach the end as we may have triggered
            // it in a prior update and no longer want it to display.
            HideError();
        } catch (Exception) {
            ShowError("myText is empty!");
        }
    }

    #region Move to a base page or a helper class if it helps reduce duplication

    private void HideError() {
        ScriptManager.RegisterStartupScript(Page, GetType(), "HideErrorMessageScript", HideErrorMessageScript(), true);
    }

    private void ShowError(string errorMessage) {
        ScriptManager.RegisterStartupScript(Page, GetType(), "ErrorMessageScript", ErrorMessageScript(errorMessage), true);
    }

    private static string HideErrorMessageScript() {
        return @"
$(document).ready(function() {
    $('#errorMessagePlaceHolder').hide();
});
";
    }

    private static string ErrorMessageScript(string errorMessage) {
        return
            string.Format(
                @"
$(document).ready(function() {{
    $('#errorMessagePlaceHolder').html('{0}');
    $('#errorMessagePlaceHolder').show();
}});
",
                errorMessage);
    }

    #endregion

}

答案 3 :(得分:2)

我觉得还没有人真正回答过整个问题,所以让我试一试。

  

这台Console.Writeline是否适合我正在尝试做的事情?

可能不会,除非您只是想在调试时希望调试信息出现在输出窗口中。有些人喜欢将信息输出到控制台,即使在发布版本中也是如此,因此如果您想对错误进行操作,那么这是一个有效的选择,但您还应向用户显示友好的错误消息和/或记录某种持久性的错误(例如日志文件)。上面的所有答案都建议您向用户显示错误通知的方法。

  

这是否适用于UpdatePanels?

如果您的触发器等设置正确,我们没有理由不这样做(而且我们知道这是因为您说您可以点击 Console.WriteLine 断点)。我想知道您的控制台输出是否正常工作但是您在错误的地方寻找它?在Web应用程序的典型配置中,它应出现在您用于调试的Visual Studio实例的“输出”窗口中。


关于我认为您要问的建议,“如果加载该更新面板的内容时出错,如何让我的错误消息显示在更新面板中?” ...

我建议采用与上述nekno提案类似的方法。您可以动态添加一个控件,其文本可以在更新面板请求处理期间设置为错误字符串,或者您甚至可以在页面上具有最初隐藏/折叠控件,该控件仅在出现错误时设置为可见。我更喜欢后一种方法,因为它更易于维护。您可以从ASPX页面的标记/显示视图中完全控制错误标签的外观。

答案 4 :(得分:1)

在LoadData()方法运行后,您是否在UpdatePanel上调用.update()?我认为UpdatePanel不会自动触发,除非回发源自它内部。

前:

Protected void btnLoad_Click(object sender, EventArgs e)
{
    LoadData();
    MyUpdatePanel.Update(); 
} 

更新:通过为创建错误的按钮注册类似Response.Write()的触发器,我可以让<Triggers><asp:PostBackTrigger ControlID="btn1" /></Triggers>在UpdatePanel中工作。

答案 5 :(得分:1)

您是在尝试记录错误还是显示错误?如果您要显示它们,您应该:

在您的母版页上,创建一个显示错误的位置(可能位于导航栏下方或底部附近:

<asp:ContentPlaceHolder id='cphError'></asp:ContentPlaceHolder>

每当出现错误时,您可以按原样调用错误函数,但不是使用Response.Write()或Console.WriteLine()写出文本,而是可以在其中添加标签:

Label lError = new Label();
lError.CssClass = '..';
lError.Text = '..';
cphError.Controls.Add(lError);

这将帮助您显示错误,但AJAX仍然是一个问题。此时,您有两个选择:

  1. 由于更新面板更新了其他更新面板,您可以围绕cphError包装更新面板,这样您的AJAX调用仍会更新该区域

  2. OR:您可以使用ClientScript.RegisterStartupScript创建错误标签。 (如果您没有静态错误消息点,则此方法最好)

答案 6 :(得分:1)

将一个Panel放在master上,用AjaxToolKit中的modalpopupextender扩展它。当引发错误时,将字符串writer的内容写入面板E.g中的标签。标签lbl =(标签)Master.FindControl() lbl.text = StringWriter.ToString();

//现在访问模态弹出窗口 AjaxControlToolkit.ModalPopupExtender MPE =(AjaxControlToolkit.ModalPopupExtender)Master.findControl(“”); //并展示它 MPE.Show();

Modal需要一个隐藏按钮才能用作目标控件,但不需要用户输入。我在页面上使用以下代码完成此操作:

            <asp:Button ID="btnDummyOK" runat="server" Style="display: none;" />
        <asp:ModalPopupExtender ID="mpePnlErrors" runat="server" TargetControlID="btnDummyButton" PopupControlID="pnlErrirs" BackgroundCssClass="modalBackground" CancelControlID="btnCancel" OkControlID="btnOK" />
祝你好运

答案 7 :(得分:0)

我认为Console.WriteLine不能在asp.net应用程序上工作,我认为在更新面板中你可以简单地触发抛出New Exception(友好的错误消息),它将出现在一个警告框中。