Рекомендации для хороших способов отображения пользовательских сообщений в asp.net? - PullRequest
8 голосов
/ 27 июля 2010

У меня есть приложение, полное страниц и пользовательских элементов управления, многие из которых имеют один или несколько элементов управления метками для отображения различных сообщений пользователю.

Пример: пользовательский элемент управления AddCompany.ascx, обычно используемый на странице Company.aspx (с App.Master MasterPage), имеет метку с именем "OutOfCreditLabel" с Text = "Ошибка: вы не можете создать новую компанию, так как вы вне кредита ». Код проверяет кредит и показывает метку, если необходимо.

Я хочу избавиться от всех этих ярлыков повсюду, и у меня есть метод, который я могу вызвать из любого места, например

ShowUserMessage("Text goes here");

В предыдущих проектах я реализовал это как одну метку на главной странице и публичный метод в .master.cs - до тех пор, пока страница имеет строку

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

в нем это работает - но я не могу заставить его работать на пользовательских элементах управления (.ascx.cs). Есть ли хитрость в этом?

Или ... Есть ли лучший способ?

Что бы вы порекомендовали для «глобального» метода сообщений пользователя, который работает из любой точки сайта?

Какие-нибудь хорошие решения jQuery, возможно?

Update
RPM1984 попросил дать дополнительные разъяснения, поэтому я пытаюсь задать это по-другому:

Мне нужен метод, который я могу вызвать из выделенного кода (страницы или пользовательского элемента управления ), который затем отображает любой текст, который я указываю пользователю, например, как stackoverflow сообщает вам о новых ответах на ваш вопрос при следующем посещении сайта. Это может быть вверху окна (например, SO) или где-то на странице, не имеет значения. Важно то, что это «глобальный» подход, а не наличие различных предупреждений javascript и ярлыка asp: на каждой странице и пользовательском элементе управления проекта.

Примерно такой сценарий:

Пользователь нажимает кнопку «Создать виджет» на моем элементе управления «Менеджер виджетов» на моей странице. В обработчике событий есть:

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

Это приводит к тому, что пользователь видит: «Извините, вы не можете создавать виджеты; у вас нет кредита». Либо во всплывающем окне, либо в красном тексте на странице где-нибудь или вверху, например, StackOverflow, все в порядке

Имеет ли это смысл?

Ответы [ 9 ]

2 голосов
/ 27 июля 2010

Почему бы не простой метод расширения старой школы 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" %>

ИЗМЕНИТЬ после обновления вопроса

Хорошо, теперь я вижу, что вы пытаетесь сделать. Я бы рекомендовал делать все это на стороне клиента.

То есть на главной странице создайте изначально скрытый <div> с уникальным идентификатором:

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

Затем создайте вспомогательный метод где-нибудь в вашем веб-проекте, выводя некоторый скрипт.

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, вам не нужно жестко кодировать скрипт в методе. Вы можете создать функцию JavaScript, которая принимает строку и изменяет HTML-код div, а затем просто вызывает функцию.

Все зависит от того, насколько сложным является ваше «сообщение», нужны ли вам специальные элементы управления сервером, интернационализация и т. Д.

Но это, безусловно, самый простой способ достичь желаемого (ИМХО).

2 голосов
/ 05 августа 2010

Лично я предпочел бы использовать словарь HttpContext.Current.Items с пользовательским элементом управления. Аналогичен подходу Кейта Блестоуна, но не требует произвольно названного элемента управления на странице; это очень ясно дает понять, что происходит. Вы можете достаточно легко упаковать его в один класс в качестве серверного элемента управления, но здесь нужно перейти к стандартному веб-проекту.

Чтобы зарегистрировать сообщение в своем коде:

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

~ \ Controls \ SiteMessage.aspx

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

~ \ Controls \ 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);
    }
}
1 голос
/ 14 ноября 2010

Создайте событие в пользовательском элементе управления, подпишитесь на событие со страницы.Обработчик событий обновляет свойство пользовательской страницы.Похоже, наименьшее количество движущихся частей.

1 голос
/ 05 августа 2010

Безопасное всплывающее окно 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 Subs"

    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)
1 голос
/ 30 июля 2010

Я хотел бы предложить использовать класс для пользовательской страницы (унаследованной от 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 и использовать эту функцию для показа ваших сообщений вашим клиентам

1 голос
/ 29 июля 2010

Некоторые хорошие ответы, но ...

  1. К Роберт W : главная страница подразумевает работу, но она требует сильной связи (знания) с главной страницейтип.Главные страницы обычно должны влиять только на стиль, верно?Например, я должен иметь возможность изменять главные страницы, не ломая свое приложение.
  2. SubPortal : да, очень умно, но ... слишком умно для меня.Также есть проблема с главной страницей.
  3. RPM1984 : опять же, слишком умен для меня!

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 ("недостаточно кредитов") .Надеюсь, это то, что вы ищете ... Кит

1 голос
/ 28 июля 2010

Наличие метода SetStatus в MasterPage - это всегда способ, которым я это делал, чтобы получить доступ к 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 для него, в противном случае вы получите то же сообщение о состоянии для постбэков, которое вам не нужно,

1 голос
/ 27 июля 2010

Я искал способ отображения сообщения для всего сайта. Я нашел jnotifica . Это похоже на панель stackoverflow в верхней части страницы.

Сайт автора в данный момент недоступен.

1 голос
/ 27 июля 2010

На главной странице добавьте следующие элементы управления: скрытое поле 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" />

ПРИМЕЧАНИЕ. Вы можете добавить другой элемент управления html с другим идентификатором в элемент управления ASCX и использовать его для отображения сообщения вместо 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!");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...