Member 11403304 Ответов: 3

Как мне сделать свой метод для заполнения списка?


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

Когда я навожу курсор мыши на объект staffEmails, я вижу count = 16. есть 16 имен и электронных писем. Когда я разворачиваю staffEmails, я вижу [0] {FTACaseReseting.Модели.GetRequestorInfoModel}. Когда я развернуть это я вижу отображаемое имя "Джим, Доу" электронной почты "Jim.Doe@gmail.com". Однако мой список не заполнен этим именем или другими именами.

Я не знаю, как изменить свой метод, чтобы список был заполнен именами. Пожалуйста помочь

Вот мой метод.

Что я уже пробовал:

public async void PopulateAdditionalStaffEmailListBox()
        {
            try
            {
                List<GetRequestorInfoModel> staffEmails = new List<GetRequestorInfoModel>();
                staffEmails = await FTACaseReseting.Controllers.RequestorInfoController.GetAllRequestorInfoes();
                staffEmails = staffEmails.OrderBy(x => x.DisplayName).ToList();
                AdditionalStaffEmailListBox.DataSource = staffEmails;

                AdditionalStaffEmailListBox.DataSource = "DisplayName";
                AdditionalStaffEmailListBox.DataValueField = "Email";
                //Clear all selections in the listbox after populating
                AdditionalStaffEmailListBox.ClearSelection();
            }
            catch (Exception ex)
            {
                string errorMsg = string.Format("An error has occured in {0}. \nException:\n{1}", "AdditionalStaffEmailListBox()", ex.Message);
                Response.Write("<script>alert('" + errorMsg + "')</script>");
            }
        }

3 Ответов

Рейтинг:
12

Richard Deeming

Цитата:
public async void PopulateAdditionalStaffEmailListBox()
Вы нашли одну из многих причин для этого избегать async void методы[^]. :)

Ваш Page_Load вызовы обработчика событий PopulateAdditionalStaffEmailListBox Этот метод доходит до первого await выписка и возврат.

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

В какой-то более поздний момент await завершает, и остальная часть PopulateAdditionalStaffEmailListBox метод работает. Но уже слишком поздно - ответ уже отправлен обратно клиенту. Все, что вы сейчас добавите в список, будет просто выброшено.

Есть несколько способов решить эту проблему. Оба потребуют, чтобы вы добавили Async="True" к вашим услугам <%@ Page %> директива. И то и другое потребует, чтобы вы изменили свое мнение. PopulateAdditionalStaffEmailListBox метод, чтобы возвратить Task.

Вариант 1:
Воспользуйся то RegisterAsyncTask метод[^]:
public async Task PopulateAdditionalStaffEmailListBox() { ... }

public void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        Page.RegisterAsyncTask(new PageAsyncTask(PopulateAdditionalStaffEmailListBox));
    }
}

Вариант 2:
Воспользуйся асинхронные модели обязательного[^] (требуется .NET 4.6 или более поздняя версия):
public async Task<IEnumerable<GetRequestorInfoModel>> GetAdditionalStaffEmails()
{
    var staffEmails = await FTACaseReseting.Controllers.RequestorInfoController.GetAllRequestorInfoes();
    return staffEmails.OrderBy(x => x.DisplayName);
}
Разметка:
<asp:ListBox ID="AdditionalStaffEmailListBox" runat="server"

    SelectMethod="GetAdditionalStaffEmails"

    DataTextField="DisplayName"

    DataValueField="Email"

/>

Использование асинхронных методов в ASP.NET 4.5 | Microsoft Docs[^]


Member 11403304

Что является отличным решением. Но прежде чем я попробую это сделать. Я хочу, чтобы вы увидели, как загружается моя страница в данный момент. Вот этот код. Может быть, это поможет вам понять, что я делаю.
частная _Default_Load недействительным(объект отправителя, EventArgs в электронной)
{
этот.PopulateAdditionalStaffEmailListbox();
}

Richard Deeming

Да, вот именно так, как я думал, что это было. :)

Member 11403304

После внесения предложенных вами изменений поле AdditionalStaffEmailListBox заполняется. Однако объект отображается вместо имен. Это то, что населено FTACaseReseting.Модель.GetRequestorInfoModel

Richard Deeming

Вам нужно будет установить DataValueField и DataTextField в разметке. Я обновил свой ответ.

Member 11403304

Дааа. Это сработало. Так как я нахожусь в процессе разработки веб-приложения. Вы, вероятно, увидите много вопросов от меня. Мне любопытно, был ли способ отправить вам электронное письмо с вопросом/вопросами или постом здесь, и вы его увидите?

Richard Deeming

Разместите их здесь - задавать вопрос[^].

Таким образом, другие люди тоже могут помочь. :)

Member 11403304

Теперь я хотел бы добавить код, который у меня был раньше в try catch, потому что я хотел бы поймать любое исключение. Когда я добавил попробовать поймать в общественных асинхронного задачу<интерфейс IEnumerable&ЛТ;getrequestorinfomodel&ГТ;&ГТ; GetAdditionalStaffEmails() метод, я получаю сообщение 'помощью _default.GetAdditionalStaffEmails()':не все пути кода возвращают значение. Как мне решить эту проблему? Мне нужно попробовать поймать

Richard Deeming

Вам нужно будет вернуть значение по умолчанию из вашего catch блок:

public async Task<IEnumerable<GetRequestorInfoModel>> GetAdditionalStaffEmails()
{
    try
    {
        var staffEmails = await FTACaseReseting.Controllers.RequestorInfoController.GetAllRequestorInfoes();
        return staffEmails.OrderBy(x => x.DisplayName);
    }
    catch (Exception ex)
    {
        string errorMsg = string.Format("An error has occured in {0}. \nException:\n{1}", "GetAdditionalStaffEmails()", ex.Message);
        Response.Write("<script>alert(" + HttpUtility.JavaScriptStringEncode(errorMsg, true) + ")</script>");
        return Enumerable.Empty<GetRequestorInfoModel>();
    }
}
NB: Вам нужно будет закодировать сообщение об ошибке перед его визуализацией, если оно содержит какие-либо символы, которые недопустимы как часть строки JavaScript.

Member 11403304

Еще раз спасибо, Ричард. Это решило мою проблему. Я также понимаю, почему мне нужно сделать это таким образом, то есть кодировать сообщение об ошибке перед его рендерингом. Я многому учусь, продолжая разрабатывать это веб-приложение

Member 11403304

Я опубликую новый вопрос, потому что застрял на заполнении списка RequestorDropDownList. Пользователю будет разрешено выбрать только одно имя из списка.

Рейтинг:
1

Richard MacCutchan

AdditionalStaffEmailListBox.DataSource = staffEmails;

AdditionalStaffEmailListBox.DataSource = "DisplayName";

Это второе утверждение уничтожает список источников данных.


Рейтинг:
0

phil.o

Вы можете попробовать заменить его

AdditionalStaffEmailListBox.DataSource = "DisplayName";
с
AdditionalStaffEmailListBox.DataTextField = "DisplayName";


Member 11403304

Единственные доступные опции для AdditionalStaffEmailListBox. это утилизировать, утилизировать SupportDisabledAttribute.

Когда я навожу курсор мыши на AdditionalStaffEmailListBox, я вижу AdditionalStaffEmailListBox{System.Web.UI.WebControls.список}

phil.o

Пожалуйста, смотрите мой обновленный ответ.