Создание и отображение динамических сообщений об ошибках (не работает внутри UpdatePanel) - PullRequest
2 голосов
/ 20 июля 2011

Мои веб-формы наследуют класс с именем MyPageMain, который наследуется System.Web.UI.Page и находится в папке App_Code.

В этом MyPageMain классе я создал этот метод для записи и вывода исключений (сообщений об ошибках):

public string Error(Exception pException, string pFriendlyMessage)
{
    using (BusError erro = new BusError())
    {
        int? errorId = //HERE Routine to log the error;

        StringWriter stringWriter = new StringWriter();

        using (HtmlTextWriter writer = new HtmlTextWriter(stringWriter))
        {

            writer.AddAttribute(HtmlTextWriterAttribute.Class, "erroMain");
            writer.RenderBeginTag(HtmlTextWriterTag.Div); //<div>

            writer.RenderBeginTag(HtmlTextWriterTag.P); //<p>
            writer.Write(pFriendlyMessage);
            writer.RenderEndTag(); // </p>
            writer.RenderBeginTag(HtmlTextWriterTag.Small); 
            writer.Write("Event tracker:");
            writer.Write(errorId);
            writer.RenderEndTag(); 

            writer.RenderEndTag(); // </div>
            Console.WriteLine(stringWriter.ToString());
        }

    }
}

Затем, когда на странице возникает какое-то исключение, я называю это так:

    Protected void btnLoad_Click(object sender, EventArgs e)
    {
         LoadData();
    }        

    private void LoadData()
    {
        try
        {
             //Loading some data here.
        }
        catch (Exception ex)
        {
             Error(ex, "Unexpected error trying to load data.");
        }
    }

Это нормально, но не работает ... Я думаю, что одной из причин может быть тот факт, что все это находится внутри UpdatePanel . Любые предложения о том, как сделать эту работу?

Это Console.Writeline подходит для того, что я пытаюсь сделать? Будет ли это работать на UpdatePanels?

Уже пробовал с Response.Write(...) и все работает. Но не внутри UpdatePanel

Ответы [ 8 ]

3 голосов
/ 07 августа 2011

Когда вы используете UpdatePanel, вы можете обновлять содержимое на панели только во время асинхронной обратной передачи, инициированной с этой панели, поэтому ваше сообщение об ошибке должно появиться где-то в пределах UpdatePanel. (То есть, если вы не установите UpdateMode="Always" для одного из UpdatePanels, его содержимое будет обновляться при каждой асинхронной и полной обратной передаче. Но это не поможет вам, если вы не поместите свое сообщение об ошибке в собственное UpdatePanel с UpdateMode="Always", что потребует от вас добавления UpdatePanel к каждой странице. Я понимаю, что не , что вы хотите сделать.)

Следующий пример будет работать, чтобы добавить сообщение об ошибке вверху UpdatePanel.

Вам потребуется добавить параметр Control errorParent в ваш метод Error, чтобы он мог добавить сообщение об ошибке в качестве дочернего элемента управления для этого родительского элемента управления.

В вашем блоке catch просто передайте любой контейнерный элемент управления, где вы хотите, чтобы появилось сообщение об ошибке. Этот элемент управления должен быть контейнером для принятия дочерних элементов управления, поэтому он должен быть представлен в виде тега <div> или <span>, например asp:Panel или asp:UpdatePanel.

.

В приведенном ниже примере вы можете использовать errorParent.Controls.Add(errorControl), чтобы показать сообщение об ошибке внизу UpdatePanel, или использовать AddAt() с другим индексом. Просто убедитесь, что индекс будет работать на каждой странице.

Возьмите родительский элемент управления и добавьте новый Literal дочерний элемент управления:

public string Error(Exception pException, string pFriendlyMessage, Control errorParent)
{
    using (BusError erro = new BusError())
    {
        int? errorId = //HERE Routine to log the error;

        Literal errorControl = new Literal();
        errorControl.Text = String.Format("<div class=\"errorMain\"><p>{0}</p><small>Event Tracker: {1}</small></div>", pFriendlyMessage, errorId);
        errorParent.Controls.AddAt(0, errorControl);
    }
}

Передача в родительский контроль:

private void LoadData()
{
    try
    {
         //Loading some data here.
    }
    catch (Exception ex)
    {
         Error(ex, "Unexpected error trying to load data.", MyUpdatePanel.ContentTemplateContainer);
    }
}
2 голосов
/ 10 августа 2011

Мне кажется, что на самом деле никто еще не ответил на весь вопрос, поэтому позвольте мне попробовать.

Подходит ли этот Console.Writeline для того, что я пытаюсь сделать?

Вероятно, нет, если только вы не хотите, чтобы отладочная информация появлялась в окне вывода при отладке.Некоторые люди предпочитают выводить информацию на консоль, даже в сборке релиза, и поэтому, если вы хотите сделать это с вашими ошибками, это правильный выбор, но вы также должны показывать дружественное сообщение об ошибке пользователю и / или ведение журнала.ошибка в какой-то персистентности (например, файл журнала).Во всех приведенных выше ответах предлагаются способы показа пользователю некоторого уведомления об ошибке.

Будет ли это работать на UpdatePanels?

Нет НЕТпричина, по которой этого не следует делать, если ваши триггеры и тому подобное настроены правильно (и мы знаем, что это так, потому что вы сказали, что можете достичь точки останова Console.WriteLine ).Интересно, нормально ли работает ваш вывод на консоль, но вы ищете его не в том месте?В типичной конфигурации для веб-приложения оно должно появиться в окне «Вывод» экземпляра Visual Studio, который вы используете для отладки.


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

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

2 голосов
/ 07 августа 2011

Многие ответы танцуют вокруг вопроса. <a href="http://msdn.microsoft.com/en-us/library/xf2k8ftb.aspx" rel="nofollow">Console.WriteLine</a> - это команда, используемая для вывода строки текста для консольного приложения (командная строка). Это веб-приложение. Таким образом, вы либо используете <a href="http://msdn.microsoft.com/en-us/library/1463ysyw.aspx" rel="nofollow">Response.Write</a>, чтобы выплевывать строку в поток ответа, либо устанавливаете текст элемента управления Literal, который уже находится на странице, и устанавливаете его как видимый (по умолчанию скрытый).

Так как я сам полностью пропустил деталь UpdatePanel, вот альтернативное решение, чтобы восполнить это. В моем примере используется скрытый div и некоторый jQuery с использованием элемента управления ScriptManager для ввода текста в div, который находится за пределами UpdatePanel. Исходя из условий метода go_Click для кнопки, он будет показывать или скрывать сообщение об ошибке, используя jQuery, который вставляется в серверную часть страницы во время обновления UpdatePanel.

Обратите внимание, что при использовании AJAX очень важно использовать функции ScriptManager для регистрации JavaScript, а не Page.ClientScript. Использование последнего не добавит JS на страницу.

Разметка страницы

<div id="errorMessagePlaceHolder" class="error" style="display:none;">
</div>
<asp:UpdatePanel ID="myPanel" runat="server">
    <ContentTemplate>
        <asp:TextBox ID="myText" runat="server" />
        <asp:Button ID="go" Text="GO" runat="server" OnClick="go_Click" />
    </ContentTemplate>
</asp:UpdatePanel>

Код страницы позади

public partial class _Default : Page {
    protected void go_Click(object sender, EventArgs e) {
        try {
            // Do something that can throw an exception

            // Hide the error if we reach the end as we may have triggered
            // it in a prior update and no longer want it to display.
            HideError();
        } catch (Exception) {
            ShowError("myText is empty!");
        }
    }

    #region Move to a base page or a helper class if it helps reduce duplication

    private void HideError() {
        ScriptManager.RegisterStartupScript(Page, GetType(), "HideErrorMessageScript", HideErrorMessageScript(), true);
    }

    private void ShowError(string errorMessage) {
        ScriptManager.RegisterStartupScript(Page, GetType(), "ErrorMessageScript", ErrorMessageScript(errorMessage), true);
    }

    private static string HideErrorMessageScript() {
        return @"
$(document).ready(function() {
    $('#errorMessagePlaceHolder').hide();
});
";
    }

    private static string ErrorMessageScript(string errorMessage) {
        return
            string.Format(
                @"
$(document).ready(function() {{
    $('#errorMessagePlaceHolder').html('{0}');
    $('#errorMessagePlaceHolder').show();
}});
",
                errorMessage);
    }

    #endregion

}
2 голосов
/ 03 августа 2011

Поскольку ваш метод Error возвращает строку, вы можете вернуть сообщение об ошибке и отобразить его.

Поместите Literal в вашу UpdatePanel (возможно, в MasterPage, так что вам не нужно писать его для всех 40 или более страниц),Когда генерируется исключение, обработайте его с помощью метода Error и установите возвращенное сообщение равным Literal.

Console.WriteLine не может использоваться в ASP.NET .Вместо этого используйте Debug.WriteLine .Он будет записывать в окно вывода в VisualStudio.

1 голос
/ 09 августа 2011

Поместите панель на мастер, расширьте ее с помощью modalpopupextender в AjaxToolKit.При возникновении ошибки запишите содержимое средства записи строк в метку на панели. Например, Метка lbl = (Label) Master.FindControl () lbl.text = StringWriter.ToString ();

// Теперь доступмодальное всплывающее окно AjaxControlToolkit.ModalPopupExtender MPE = (AjaxControlToolkit.ModalPopupExtender) Master.findControl ("");// и показываем его MPE.Show ();

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

            <asp:Button ID="btnDummyOK" runat="server" Style="display: none;" />
        <asp:ModalPopupExtender ID="mpePnlErrors" runat="server" TargetControlID="btnDummyButton" PopupControlID="pnlErrirs" BackgroundCssClass="modalBackground" CancelControlID="btnCancel" OkControlID="btnOK" />

Удачи

1 голос
/ 08 августа 2011

Вы пытаетесь регистрировать ошибки или отображать их? Если вы пытаетесь отобразить их, вам следует:

На главной странице создайте место, где будут отображаться ваши ошибки (возможно, под панелью навигации или в нижней части:

<asp:ContentPlaceHolder id='cphError'></asp:ContentPlaceHolder>

Каждый раз, когда вы получаете сообщение об ошибке, вы можете вызывать функцию ошибки как есть, но вместо того, чтобы записывать текст с помощью Response.Write () или Console.WriteLine (), вы можете добавить туда метку:

Label lError = new Label();
lError.CssClass = '..';
lError.Text = '..';
cphError.Controls.Add(lError);

Это поможет вам с отображением ошибки, но AJAX все еще будет проблемой. На данный момент у вас есть два варианта:

  1. Поскольку панели обновления обновляют другие панели обновления, вы можете обернуть панель обновления вокруг cphError, таким образом ваши вызовы AJAX все равно обновят эту область

  2. ИЛИ: Вы можете использовать ClientScript.RegisterStartupScript для создания метки ошибки. (Этот метод предпочтителен, только если у вас нет статического сообщения об ошибке)

1 голос
/ 20 июля 2011

Вы вызываете .update () на UpdatePanel после запуска метода LoadData ()?Я думаю, что UpdatePanel не будет запускаться автоматически, если только обратная передача не происходит изнутри.

Пример:

Protected void btnLoad_Click(object sender, EventArgs e)
{
    LoadData();
    MyUpdatePanel.Update(); 
} 

Обновление: мне удалось заставить Response.Write() работать в UpdatePanel, зарегистрировав триггер, подобный этому <Triggers><asp:PostBackTrigger ControlID="btn1" /></Triggers>, для кнопки, которая создаст ошибку.

0 голосов
/ 03 августа 2011

Я думаю, что Console.WriteLine не работает с приложением asp.net, и я думаю, что внутри панели обновлений вы можете просто запустить бросок New Exception (понятное сообщение об ошибке), и он появится в окне предупреждения.

...