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

时间:2010-05-07 18:11:52

标签: c# asp.net event-driven-design centralized

我在这里寻找一些指导。

在我的网站上,我把东西放在Web用户控件中。例如,我将有一个NewsItem控件,一个文章控件,一个ContactForm控件。

这些会出现在我网站的不同位置。

我正在寻找的是这些控件将消息传递到它们存在的页面的方式。

我不想紧紧地联系他们,所以我想我必须与Events / Delegates一起做。不过,我对如何实现这一点有点不清楚。

几个例子:

1

提交联系表格。在提交之后,我不想用“已发送邮件”替换自己来限制该邮件的位置,我只想通过状态消息和建议的行为通知页面控件已打开。因此,消息将包含要呈现的文本以及enumDisplayAs.Popup

DisplayAs.Success

2

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

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

同样,我不想紧密绑定或依赖页面上存在的控件。我希望控件能够引发这些事件,但如果需要,页面可以忽略它们。

我能以正确的方式解决这个问题吗?

我喜欢code样本只是为了让我开始。

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

3 个答案:

答案 0 :(得分:2)

以下假设您知道您的控件都放在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

答案 1 :(得分:2)

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

父ASPX

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

家长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();
}

答案 2 :(得分:1)

数据注释验证器对这类事物非常有用。通常它们在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