Рекомендации для хороших способов отобразить пользовательские сообщения в asp.net?

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

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

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

ShowUserMessage("Text goes here");

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

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

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

Или... Существует ли лучший путь?

Что Вы рекомендовали бы для "глобального" пользовательского метода сообщения, который работает откуда-либо в сайте?

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

Обновление
RPM1984 попросил дальнейшее разъяснение, таким образом, я пытаюсь спросить это другой путь:

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

Что-то вроде этого сценарий:

Пользователь нажимает кнопку "Create Widget" на моем "пользовательском элементе управления" менеджера по виджету на моей странице. В конечном счете обработчик:

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

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

Это имеет смысл?

8
задан MGOwen 28 July 2010 в 07:36
поделиться

8 ответов

На главной странице добавьте следующие элементы управления: скрытое поле 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!");
1
ответ дан 5 December 2019 в 15:17
поделиться

Я всегда использовал метод SetStatus в MasterPage, чтобы получить доступ к MasterPage изнутри пользовательского элемента управления, просто создайте частное свойство в пользовательском элементе управления (или создайте 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
ответ дан 5 December 2019 в 15:17
поделиться

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

Сайт автора сейчас не работает.

1
ответ дан 5 December 2019 в 15:17
поделиться

Why not a simple HTML "old-school" extension method? (i.e static method)

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

Then in your HTML:

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

In your main master page, just import the namespace:

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

EDIT after question updated

Ok, i see what you're trying to do now. I would recommend doing it all client-side.

That is, in your main master page, create an initially hidden

with a unique id:

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

Then create a helper method somewhere in your web project, rendering out some script.

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

Of course, this is just a guideline. You dont have to use jQuery, you don't have to hardcode the script in the method. You could create a JavaScript function that accepts a string and modifies the HTML of the div, then just call the function.

It all depends on how complicated your "message" is, if you need special server controls, internationalization, etc.

But this is certainly the easiest way to accomplish what you want (IMHO).

2
ответ дан 5 December 2019 в 15:17
поделиться

Несколько хороших ответов, но ...

  1. Для Роберта В. : главная страница impl работает, но требует сильной связи (знания) с типом главной страницы. Главные страницы обычно должны влиять только на стиль, верно? Например. Я должен иметь возможность изменять главные страницы, не нарушая работу моего приложения.
  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
ответ дан 5 December 2019 в 15:17
поделиться

Я хотел бы предложить использовать класс для настраиваемой страницы (унаследованный от 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
ответ дан 5 December 2019 в 15:17
поделиться

Лично я бы предпочел использовать словарь 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);
    }
}
2
ответ дан 5 December 2019 в 15:17
поделиться

Всплывающее окно, безопасное для 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
ответ дан 5 December 2019 в 15:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: