如何在 Asp.Net 页面上的一处处理所有错误/消息?

发布于 2024-08-31 12:41:24 字数 782 浏览 5 评论 0原文

我在这里寻找一些指导。

在我的网站上,我将内容放入 Web 用户控件中。例如,我将有一个 NewsItem 控件、一个 Article 控件、一个 ContactForm 控件。

这些将出现在我网站上的各个位置。

我正在寻找一种方法,让这些控件将消息传递到它们所在的页面。

我不想将它们紧密结合在一起,所以我想我必须对事件/代表执行此操作。不过,我有点不清楚如何实现这一点。

几个示例:

1

提交联系表格。提交后,我不想将其自身替换为限制该消息放置的“您的邮件已发送”,而是只想通过状态消息和建议的行为通知页面该控件已打开。因此,消息将包含要呈现的文本以及 enum,如 DisplayAs.PopupDisplayAs.Success

2

文章控件查询Article 对象的数据库。数据库返回异常。自定义异常与 DisplayAs.Error 枚举一起传递到页面。该页面处理此错误并在错误所在的位置显示它。

我正在尝试完成类似于 ValidationSummary 控件的操作,但我希望页面能够在枚举感觉合适时显示消息。

同样,我不想紧密绑定或依赖页面上现有的控件。我希望控件引发这些事件,但页面可以根据需要忽略它们。

我以正确的方式处理这件事吗?

我想要一个 code 示例来帮助我开始。

我知道这是一个更复杂的问题,所以我会在投票/选择答案之前等待更长的时间。

I'm looking for some guidance here.

On my site I put things in Web user controls. For example, I will have a NewsItem Control, an Article Control, a ContactForm control.

These will appear in various places on my site.

What I'm looking for is a way for these controls to pass messages up to the Page that they exist on.

I don't want to tightly couple them, so I think I will have to do this with Events/Delegates. I'm a little unclear as to how I would implement this, though.

A couple of examples:

1

A contact form is submitted. After it's submitted, instead of replacing itself with a "Your mail has been sent" which limits the placement of that message, I'd like to just notify the page that the control is on with a Status message and perhaps a suggested behaviour. So, a message would include the text to render as well as an enum like DisplayAs.Popup or DisplayAs.Success

2

An Article Control queries the database for an Article object. Database returns an Exception. Custom Exception is passed to the page along with the DisplayAs.Error enum. The page handles this error and displays it wherever the errors go.

I'm trying to accomplish something similar to the ValidationSummary Control, except that I want the page to be able to display the messages as the enum feels fit.

Again, I don't want to tightly bind or rely a control existing on the Page. I want the controls to raise these events, but the page can ignore them if it wants.

Am I going about this the right way?

I'd love a code sample just to get me started.

I know this is a more involved question, so I'll wait longer before voting/choosing the answers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

海风掠过北极光 2024-09-07 12:41:24

您可以将子页面中发生的事件向上冒泡到父页面。父页面可以注册该事件并利用它(如果有用)。

父级 ASPX

<uc1:ChildControl runat="server" ID="cc1" OnSomeEvent="cc1_SomeEvent" />

父级 c#

protected void cc1_SomeEvent(object sender, EventArgs e)
{
    // Handler event
}

子级 C#

public event EventHandler OnSomeEvent;

protected void ErrorOccurInControl()
{
     if (this.OnSomeEvent != null)
     {
          this.OnSomeEvent(this, new EventArgs());
     }
}

protected override void OnLoad(EventArgs e)
{
     ErrorOccurInControl();
}

You can bubble up the event occurs in child to parent page. Parent page can register that event and utilizes it (if it is useful).

Parent ASPX

<uc1:ChildControl runat="server" ID="cc1" OnSomeEvent="cc1_SomeEvent" />

Parent c#

protected void cc1_SomeEvent(object sender, EventArgs e)
{
    // Handler event
}

Child C#

public event EventHandler OnSomeEvent;

protected void ErrorOccurInControl()
{
     if (this.OnSomeEvent != null)
     {
          this.OnSomeEvent(this, new EventArgs());
     }
}

protected override void OnLoad(EventArgs e)
{
     ErrorOccurInControl();
}
拥抱我好吗 2024-09-07 12:41:24

下面假设您知道您的控件都放置在 App.YourPage 类型的页面上

这是一个快速消息框,我将其放置在 MasterPage 或 Page 上并只需调用从任何页面或控件。 (抱歉,它在 VB.net 中,而不是在 C# 中)

扩展 AddMessage 来记录并执行其他基于事务的操作(我从中提取了控制器逻辑)

您可以从任何控件

CType(Page, App.YourPage).messageBox.AddMessage(
         ctrlMessageBox.MessageTypes.InfoMessage
          ,"Updated Successfully")

:控制:

    Public Class ctrlMessageBox
        Inherits System.Web.UI.UserControl

        'List of types that a message could be
        Enum MessageTypes
            InfoMessage
            ErrorMessage
            WarningMessage
        End Enum

#Region "[Message] inner class for structered message object"
        Public Class Message
            Private _messageText As String
            Private _messageType As MessageTypes
            Public Property MessageText() As String
                Get
                    Return _messageText
                End Get
                Set(ByVal value As String)
                    _messageText = value
                End Set
            End Property
            Public Property MessageType() As MessageTypes
                Get
                    Return _messageType
                End Get
                Set(ByVal value As MessageTypes)
                    _messageType = value
                End Set
            End Property

        End Class
#End Region

        'storage of all message objects
        Private _messages As New List(Of Message)

        'Creates a Message object and adds it to the collection
        Public Sub addMessage(ByVal MessageType As MessageTypes, ByVal MessageText As String)
            Page.Trace.Warn(Me.GetType.Name, String.Format("addMessage({0},{1})", MessageType.ToString, MessageText))
            Dim msg As New Message
            msg.MessageText = MessageText
            msg.MessageType = MessageType
            _messages.Add(msg)
        End Sub

        Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
            ' Page.Trace.Warn(Me.GetType.Name, String.Format("Page_PreRender(_messages.Count={0})", _messages.Count))

        End Sub
        Public Overrides Sub RenderControl(ByVal writer As System.Web.UI.HtmlTextWriter)
            Page.Trace.Warn(Me.GetType.Name, String.Format("ctrlMessageBox.RenderControl(_messages.Count={0})", _messages.Count))
            'draws the message box on the page with all messages

            If _messages.Count = 0 Then Return
            Dim sbHTML As New StringBuilder
            sbHTML.Append("<div id='MessageBox'>")

            For Each msg As Message In _messages
                sbHTML.AppendFormat("<p><img src='{0}'> {1}</p>", getImage(msg.MessageType), msg.MessageText)
            Next

            sbHTML.Append("</div>")

            writer.Write(sbHTML.ToString)

            'dim ctrlLiteral As New Literal()
            'ctrlLiteral.Text = sbHTML.ToString
            'Me.Controls.Add(ctrlLiteral)
        End Sub

        'returns a specific image based on the message type
        Protected Function getImage(ByVal type As MessageTypes) As String
            Select Case type
                Case MessageTypes.ErrorMessage
                    Return Page.ResolveUrl("~/images/icons/error.gif")
                Case MessageTypes.InfoMessage
                    Return Page.ResolveUrl("~/images/icons/icon-status-info.gif")
                Case MessageTypes.WarningMessage
                    Return Page.ResolveUrl("~/images/icons/icon-exclaim.gif")
                Case Else
                    Return ""
            End Select
        End Function
    End Class

The following is assuming you know that your controls are all placed on a page of type App.YourPage

Here's a quick message box that I place onto the MasterPage or Page and just call from any page or control. (Sorry its in VB.net not c#)

You can extend out AddMessage to log and do other transaction based action (I pulled out our controller logic from it)

from any control:

CType(Page, App.YourPage).messageBox.AddMessage(
         ctrlMessageBox.MessageTypes.InfoMessage
          ,"Updated Successfully")

Control:

    Public Class ctrlMessageBox
        Inherits System.Web.UI.UserControl

        'List of types that a message could be
        Enum MessageTypes
            InfoMessage
            ErrorMessage
            WarningMessage
        End Enum

#Region "[Message] inner class for structered message object"
        Public Class Message
            Private _messageText As String
            Private _messageType As MessageTypes
            Public Property MessageText() As String
                Get
                    Return _messageText
                End Get
                Set(ByVal value As String)
                    _messageText = value
                End Set
            End Property
            Public Property MessageType() As MessageTypes
                Get
                    Return _messageType
                End Get
                Set(ByVal value As MessageTypes)
                    _messageType = value
                End Set
            End Property

        End Class
#End Region

        'storage of all message objects
        Private _messages As New List(Of Message)

        'Creates a Message object and adds it to the collection
        Public Sub addMessage(ByVal MessageType As MessageTypes, ByVal MessageText As String)
            Page.Trace.Warn(Me.GetType.Name, String.Format("addMessage({0},{1})", MessageType.ToString, MessageText))
            Dim msg As New Message
            msg.MessageText = MessageText
            msg.MessageType = MessageType
            _messages.Add(msg)
        End Sub

        Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
            ' Page.Trace.Warn(Me.GetType.Name, String.Format("Page_PreRender(_messages.Count={0})", _messages.Count))

        End Sub
        Public Overrides Sub RenderControl(ByVal writer As System.Web.UI.HtmlTextWriter)
            Page.Trace.Warn(Me.GetType.Name, String.Format("ctrlMessageBox.RenderControl(_messages.Count={0})", _messages.Count))
            'draws the message box on the page with all messages

            If _messages.Count = 0 Then Return
            Dim sbHTML As New StringBuilder
            sbHTML.Append("<div id='MessageBox'>")

            For Each msg As Message In _messages
                sbHTML.AppendFormat("<p><img src='{0}'> {1}</p>", getImage(msg.MessageType), msg.MessageText)
            Next

            sbHTML.Append("</div>")

            writer.Write(sbHTML.ToString)

            'dim ctrlLiteral As New Literal()
            'ctrlLiteral.Text = sbHTML.ToString
            'Me.Controls.Add(ctrlLiteral)
        End Sub

        'returns a specific image based on the message type
        Protected Function getImage(ByVal type As MessageTypes) As String
            Select Case type
                Case MessageTypes.ErrorMessage
                    Return Page.ResolveUrl("~/images/icons/error.gif")
                Case MessageTypes.InfoMessage
                    Return Page.ResolveUrl("~/images/icons/icon-status-info.gif")
                Case MessageTypes.WarningMessage
                    Return Page.ResolveUrl("~/images/icons/icon-exclaim.gif")
                Case Else
                    Return ""
            End Select
        End Function
    End Class
煞人兵器 2024-09-07 12:41:24

数据注释验证器非常适合此类事情。通常它们在 ASP.NET MVC 中使用,但它们在 WebForms 中工作得很好。您可以使用内置验证器或创建自己的自定义验证器来执行更复杂的验证。

此示例使用 VB.NET,但您应该不难看到其值:

http://adventuresdotnet.blogspot.com/2009/08/aspnet-webforms-validation-with-data.html

http://blogs.microsoft.co .il/blogs/gilf/archive/2010/04/08/building-asp-net-validator-using-data-annotations.aspx

The data annotation validators are really good for this type of thing. Typically they are used within ASP.NET MVC, but they work just fine in WebForms. You can use the built-in validators or create your own custom ones that do more complex validations.

This example is in VB.NET, but it shouldn't be hard for you to see the value:

http://adventuresdotnet.blogspot.com/2009/08/aspnet-webforms-validation-with-data.html

http://blogs.microsoft.co.il/blogs/gilf/archive/2010/04/08/building-asp-net-validator-using-data-annotations.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文