有关在asp.net中显示用户消息的好方法的建议吗?

时间:2010-07-27 02:49:52

标签: asp.net user-interface user-controls master-pages

我有一个充满页面和用户控件的应用程序,其中许多都有一个或多个标签控件,用于向用户显示各种不同的消息。

示例:通常在Company.aspx页面上使用的AddCompany.ascx用户控件(使用App.Master MasterPage)上面有一个名为“OutOfCreditLabel”的标签,文字=“错误:你因为你没有信誉,所以无法创建一家新公司“。代码检查信用额度并在需要时显示标签。

我想在所有地方摆脱所有这些标签,只是有一个我可以从任何地方调用的方法,如

ShowUserMessage("Text goes here");

在之前的项目中,我已将其作为主页面上的单个标签和.master.cs中的公共方法实现 - 只要页面有行

<%@ MasterType VirtualPath="~/App.master" %>

在其中,这有效 - 但我不能让它在用户控件(.ascx.cs)上工作。这有诀窍吗?

或者......有更好的方法吗?

对于可在网站中的任何位置使用的“全局”用户消息方法,您会推荐什么?

也许是任何不错的jQuery解决方案?

更新
RPM1984要求进一步澄清,所以我试图以不同的方式提出这个问题:

我需要一个可以从代码隐藏(页面或用户控件)调用的方法,然后将向用户显示我指定的任何文本,例如stackoverflow如何告诉您有关新内容的信息您下次访问该网站时的问题的答案。它可以在窗口的顶部(如SO)或页面的某个位置,无关紧要。重要的是它是一种“全局”方法,而不是在项目中的每个其他页面和用户控件上都有各种javascript警报和asp:label。

像这样的场景:

用户点击我页面上“widget manager”用户控件上的“Create Widget”按钮。在事件处理程序中:

if (User.IsOutOfCredit)
{
    ShowUserMessage("Sorry, you cannot create widgets; you are out of credit.");
}

这会导致用户看到“抱歉,您无法创建小部件;您的信誉不足”。无论是在页面中的弹出页面还是红色文本中,或者像StackOverflow一样在顶部,一切都很好

这有意义吗?

9 个答案:

答案 0 :(得分:2)

为什么不使用简单的HTML“老派”扩展方法? (即静态方法)

namespace Web.Helpers
{
    public class HtmlHelpers 
    {
         public static string Label(string target)
         {
              var dynamicText = SomeWhere.GetSomeCoolText();
              return String.Format("<label for='{0}'>{1}</label>", target, dynamicText);
         }
    }
}

然后在你的HTML中:

<%= HtmlHelpers.Label("sometarget") =>

在主母版页中,只需导入命名空间:

<%@ Import Namespace="Web.Helpers" %>

问题更新后编辑

好的,我看到你现在要做的事情。我建议所有客户端都这样做。

也就是说,在您的主母版页中,创建一个具有唯一ID的最初隐藏的<div>

<div id="message" style="display: none"></div>

然后在Web项目的某处创建一个帮助器方法,渲染出一些脚本。

public void DisplayMessage()
{
    string message = SomeWhere.GetSomeCoolText();
    StringBuilder script = new StringBuilder();
    script.AppendFormat("$('message').show().append("<span>{0}</span>")", message);
    Page.ClientScript.RegisterClientScriptBlock(this.GetType(), script.ToString(), true);
}

当然,这只是一个指导原则。您不必使用jQuery,您不必在方法中对脚本进行硬编码。您可以创建一个接受字符串并修改div的HTML的JavaScript函数,然后只需调用该函数。

如果您需要特殊的服务器控制,国际化等,这完全取决于您的“消息”的复杂程度。

但这肯定是实现你想要的最简单方法(恕我直言)。

答案 1 :(得分:2)

就个人而言,我更喜欢将HttpContext.Current.Items字典与自定义控件一起使用。类似于Keith Bluestone的方法,但不需要在页面上任意命名控件;它清楚地说明了发生了什么。你可以很容易地将它打包成一个类作为服务器控件,但是这里是放入一个标准的web项目。

在您的代码中注册消息:

SiteMessageUtility.Add("Test message");

要在您的页面或母版页中显示,或者在任何地方显示:

<%@ Register TagPrefix="custom" TagName="SiteMessage" Src="~/Controls/SiteMessage.ascx" %>
<custom:SiteMessage runat="server" />

以下是您需要的文件:
〜\ App_Code文件\ SiteMessageUtility.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

public static class SiteMessageUtility
{
    public static void Add(string message)
    {
        string currMessage = HttpContext.Current.Items["message"] as string;
        if (currMessage == null)
        {
            HttpContext.Current.Items["message"] = message;
        }
        else
        {
            HttpContext.Current.Items["message"] = currMessage + "<br/>" + message;
        }
    }
}

〜\控制\ SiteMessage.aspx

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="SiteMessage.ascx.cs" Inherits="Controls_SiteMessage" %>
<asp:Literal runat="server" ID="message" />

〜\控制\ SiteMessage.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class Controls_SiteMessage : System.Web.UI.UserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected override void OnPreRender(EventArgs e)
    {
        message.Text = (string)HttpContext.Current.Items["message"];
        base.OnPreRender(e);
    }
}

答案 2 :(得分:1)

在母版页上添加以下控件: hfMsg隐藏字段将保留将显示的消息 并且hfCtrl将保存将显示此消息的html控件的名称,该消息将在此示例中为lblMsg。

<label id="lblMsg" style="background-color:Yellow; border:solid 1px; width:200px;height:100px;display:none;"></label>    
    <asp:HiddenField ID="hfMsg" runat="server" />
    <asp:HiddenField ID="hfCtrl" runat="server" />

注意:您可以在ASCX控件上添加另一个具有不同ID的html控件,并使用它来显示消息而不是lblMsg。

以及以下脚本:

<script language="javascript" type="text/javascript">
    var msg = $('#<%= hfMsg.ClientID %>').attr("value");
    var ctrl = $('#<%= hfCtrl.ClientID %>').attr("value");

    if (msg != undefined && msg != "") {
        $("#" + ctrl).html(msg);            
        $("#" + ctrl).show();
    }
    else {
        $("#" + ctrl).hide();
    }
</script>

注意:脚本只是检查hfMsg控件是否有要显示的消息。

并将以下两种方法添加到母版页:

public void ShowMessage(string control, string message)
{
    this.hfCtrl.Value = control;
    this.hfMsg.Value = message;
}

public void ClearMessage()
{
    this.hfMsg.Value = string.Empty;
}

最后,您可以从任何类似的页面调用ShowMessage方法,以在母版页上显示消息:

Master.ShowMessage("lblMsg","hello world!");

如果您有一个包含html标签的用户控件(例如lblUserMsg)来显示该消息,您只需调用ShowMessage并将其传递给标签名称:

Master.ShowMessage("lblUserMsg","hello world!");

答案 3 :(得分:1)

我一直在寻找一种向用户显示消息的站点方式。我找到了jnotifica。它类似于页面顶部的stackoverflow栏。

目前作者的网站似乎已关闭。

答案 4 :(得分:1)

在MasterPage中使用SetStatus方法始终是我这样做的方式,从用户控件内部访问MasterPage,只需在usercontrol中创建一个私有属性(或者创建一个所有用户控件继承的baseControl类) ):

private TheNameSpaceOfMyMasterPage.MyMasterPage Master
{
     get { return (TheNameSpaceOfMyMasterPage.MyMasterPage)Page.Master; }
}

protected void btnSave_OnClick(object sender, EventArgs e)
{
     // Do your stuff... 

     // Set the Status
     this.Master.ShowStatus("blah blah blah");
}

此外,如果您正在使用控件来保存状态消息,请记住在其上禁用ViewState,否则您将在不希望的回发之间获得相同的状态消息。

答案 5 :(得分:1)

一些好的答案,但是......

  1. Robert W :主页面impl有效,但它确实需要与母版页类型的强耦合(知识)。母版页通常只会影响样式,对吧?例如。我应该能够在不破坏我的应用程序的情况下更改母版页。
  2. SubPortal :是的,非常聪明,但......对我来说太聪明了。还有母版页问题。
  3. RPM1984 :再次,对我来说太聪明了!
  4. MGOwen 未提及任何特殊的DHTML要求(例如,从客户端更新)。那么为什么不像他提到的那样只实现一个简单的服务器端辅助方法,找到显示消息的目标控件,并显示它?

    以下 ShowMessage 将在页面上的任何位置找到目标消息控件,并根据需要启用任何页面以覆盖默认应用程序的ShowMessage行为。

    public static class ASPHelper {
    
        // Defines something that shows a message
        public interface IShowMessage
        {
            void ShowMessage(string msg);
        }
    
        // default implementation: finds a target message display control
        // wherever it is on the page.
        static void ShowMessage_Default(string msg)
        {
            const string SHOWMESSAGE_CONTROL_ID = "ctlShowMessage"; // or whatever
    
            // find the control
            Page currentPage = HttpContext.Current.CurrentHandler as Page;
            Control ctlMessage = currentPage.FindControlRecursive(SHOWMESSAGE_CONTROL_ID);
    
            if (ctlMessage == null) 
                throw new Exception("ShowMessage control not found!" );
    
            Literal ctlMessageLiteral = ctlMessage as Literal;
            if (ctlMessageLiteral == null)
                throw new Exception("ShowMessage control must be a Literal!");
    
            // Message control should not implement viewstate -- unneccesary
            Debug.Assert(ctlMessageLiteral.EnableViewState == false);
    
            // show it
            ctlMessageLiteral.Text = msg;
            ctlMessageLiteral.Visible = true;
        }
    
        // public version for use across app & in pages
        static public void ShowMessage(string msg)
        {
            // Allow the current page to implement its own way of showing
            // messages -- provides flexibility.
            Page currentPage = HttpContext.Current.CurrentHandler as Page;
            IShowMessage showMessageImpl = currentPage as IShowMessage;
            if (showMessageImpl != null)
            {
                // Show using custom message displayer
                showMessageImpl.ShowMessage(msg);
            }
            else
            {
                // static/global/default version
                ShowMessage_Default(msg);
            }
        }
    
    } // end ASPHelper
    

    要使用,只需在页面上放置文字控件,如:

    <div><asp:Literal 
        ID="ctlShowMessage" runat="server" 
        Visible="false" 
        EnableViewState="false" 
        />
    </div>
    

    要使用,只需调用 ShowMessage ,如 ASPHelper.ShowMessage(“信用不足”)。希望这就是你要找的......基思

答案 6 :(得分:1)

我想建议使用一个类来自定义页面(继承自System.Web.UI.Page),其中添加了以下内容

protected void AlertError(string ErrorString)
{
  StringBuilder scriptBuidler = 
    new StringBuilder(@"<script type='text/javascript' language='javascript'>");
  scriptBuidler.Append(@"alert('");
  scriptBuidler.Append(ErrorString);
  scriptBuidler.Append(@"');");
  scriptBuidler.Append(@"</script>");
  AjaxControlToolkit.ToolkitScriptManager.RegisterClientScriptBlock
   (this, typeof(Page), 
    "Patient Detail Not Found", 
     scriptBuidler.ToString(), 
     false
   );
}

并从此类继承您的所有页面,而不是从system.web.ui.page继承 并使用此功能向您的客户显示您的消息

答案 7 :(得分:1)

Javascript安全弹出窗口。适用于Ajax / jQuery。

Namespace Utilities

''' <summary>
''' Utility class for injecting JavaScript into pages.  Used primarily for throwing a JavaScript alert box, with correct focus.
''' </summary>
''' <remarks></remarks>
Public Class WriteJava

区域“公共子”

    Public Shared Sub Script(ByVal script As String, ByRef p As Page, Optional ByVal scriptName As String = "")
        If String.IsNullOrEmpty(scriptName) Then
            scriptName = GetScriptName(p)
        End If
        If Not p.ClientScript.IsStartupScriptRegistered(scriptName) Then
            ToolkitScriptManager.RegisterStartupScript(p, p.GetType, scriptName, script, True)
        End If
    End Sub

    Public Overloads Shared Sub Alert(ByVal MyAlert As String, ByRef p As Page)
        Script("alert('" & Format(MyAlert) & "');", p)
    End Sub


    Private Shared Function Format(ByVal value As String) As String
        Return value.Replace("'", "\'").Replace(Chr(13), "\r").Replace(Chr(10), "\n")
    End Function

    Private Shared Function GetScriptName(ByVal p As Page) As String
        Dim i As Integer = p.AppRelativeVirtualPath.LastIndexOf("/")
        Dim pageName As String = p.AppRelativeVirtualPath.Substring(i + 1)
        Return pageName
    End Function

结束地区

End Class

结束命名空间

通过致电:

使用
Utilities.WriteJava.Alert("DANGER WILL ROBINSON", Me.Page)

答案 8 :(得分:1)

在用户控件中引发事件,从页面订阅该事件。事件处理程序更新您的自定义页面属性。似乎运动部件的数量最少。