Это приложение веб-форм asp.net с использованием .NET Framework v4.8

(Я знаю, что это старая технология, и мне не следует кодировать с ее помощью новые проекты. Я не писал ничего на asp.net более десяти лет, и когда я кодировал таким образом, веб-формы были наиболее подходящими для использования. Я буду изучите Blazor и перекодируйте это на более современной платформе в будущем. Извините, я просто пытаюсь предотвратить любые «почему вы используете веб-формы» в комментариях.)

У меня есть параметр на странице, который выглядит так:

        public Dictionary<string, string> StrategySubtypes {
        get
        {
            return (ViewState["StrategySubtypes"] == null) ? new Dictionary<string, string>() : (Dictionary<string, string>)ViewState["StrategySubtypes"];
        }
        set
        {
            ViewState["StrategySubtypes"] = value;
        }
    }

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

        protected void btnAddSubtype_Click(object sender, EventArgs e)
    {
        Dictionary<string, string> tmpStrategySubtypes = StrategySubtypes;
        StrategySubtypes.Add(txtSubtype.Text, "new");
        lbSubtypes.DataSource = StrategySubtypes;
        lbSubtypes.DataTextField = "Key";
        lbSubtypes.DataValueField = "Value";
        lbSubtypes.DataBind();
        txtSubtype.Text = String.Empty;
    }

Это просто как бы уходит в эфир. Я считаю, что происходит следующее: когда я вызываю метод Add, я получаю Dictionary от средства доступа get и выполняю метод add для этого словаря, но Add не вызывает средство доступа set, поэтому я просто привязываю данные к тот же оригинальный словарь.

Я работаю над этим с помощью следующего кода

        protected void btnAddSubtype_Click(object sender, EventArgs e)
    {
        Dictionary<string, string> tmpStrategySubtypes = StrategySubtypes;
        tmpStrategySubtypes.Add(txtSubtype.Text, "new");
        StrategySubtypes = tmpStrategySubtypes;
        tmpStrategySubtypes.GetEnumerator().Dispose();
        lbSubtypes.DataSource = StrategySubtypes;
        lbSubtypes.DataTextField = "Key";
        lbSubtypes.DataValueField = "Value";
        lbSubtypes.DataBind();
        txtSubtype.Text = String.Empty;
    }

Но это кажется неэлегантным и неуклюжим. Должен быть лучший и более правильный способ добиться этого. Мой вопрос: если я использую объект в качестве общедоступного параметра, есть ли способ вызвать метод непосредственно для этого параметра и сохранить результаты с помощью установленного средства доступа?

1
Camenwolf 27 Ноя 2021 в 18:55

1 ответ

Лучший ответ

В методе доступа get в случае null текущий код создает новый словарь, но никогда не устанавливает ViewState с этим новым экземпляром словаря. Поэтому, когда вы снова спрашиваете значение свойства StrategySubtypes, значение null все еще присутствует, и возвращается новый словарь.
Легко исправить:

public Dictionary<string, string> StrategySubtypes {
get
{
    var dict = ViewState["StrategySubtypes"] as Dictionary<string, string>;
    if(dict == null)
    {
       dict = new Dictionary<string, string>();
       ViewState["StrategySubtypes"] = dict;
    }
    return dict;
}
set
{
    ViewState["StrategySubtypes"] = value;
}
1
Steve 27 Ноя 2021 в 19:08
1
Большое спасибо! Я действительно чувствую себя глупо. Вместо того, чтобы более внимательно посмотреть, что делает мой код, я сразу пришел к выводу, что каким-то образом я не могу выполнить метод для общедоступного свойства.
 – 
Camenwolf
27 Ноя 2021 в 19:35