Могу ли я сохранить статус постбэка и восстановить его? - PullRequest
3 голосов
/ 12 марта 2012

Предположим, что после нажатия на asp:button я хотел бы сохранить фактическое «представление» с выбранным значением для каждого контроллера, например, флажок asp: или ввод, вставленный пользователями в поле ввода.

Чем я меняю страницу, со ссылкой типа "вернуться на предыдущую страницу". Я бы хотел так "восстановить" старую актуальную форму, прежде чем покинуть ее.

Возможно ли это с .NET? Или мне нужно реализовать все элементы управления в переменных и поместить их в сессию?

Ответы [ 2 ]

3 голосов
/ 12 марта 2012

Существует несколько способов сохранения или передачи значений между страницами ASP.NET.

Посмотрите здесь для получения дополнительной информации.

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

Вот мой подход, который использует Session в качестве хранилища для сохранения значений всех элементов управления типа IPostBackDataHandler.Не проверено, но, надеюсь, полезно в любом случае.

using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;

public class FormStorage
{
    private System.Web.UI.Page _page = null;

    public Dictionary<String, Dictionary<String, String>> storage
    {
        get { return (Dictionary<String, Dictionary<String, String>>)_page.Session["FormStorage"]; }
        set { _page.Session["FormStorage"] = value; }
    }

    public FormStorage(System.Web.UI.Page page)
    {
        _page = page;
        initHandler();
        if (this.storage == null)
        {
            this.storage = new Dictionary<String, Dictionary<String, String>>();
        }
        if(!this.storage.ContainsKey(_page.Request.Path))
            this.storage.Add(_page.Request.Path, new Dictionary<String, String>());
    }

    private void initHandler()
    {
        _page.Init += Init;
        _page.Load += Load;
    }

    private void Init(Object sender, EventArgs e)
    {
        loadForm();
    }

    private void Load(Object sender, EventArgs e)
    {
        saveForm();
    }

    private void loadForm()
    {
        var pageStorage = storage[_page.Request.Path];
        var e = pageStorage.GetEnumerator();
        while (e.MoveNext())
        {
            loadControl(e.Current.Key, e.Current.Value);
        }
    }

    private void loadControl(String ID, String value)
    {
        Control control = findControlRecursively(_page, ID);
        if (control != null)
        {
            setControlValue(control, value);
        }
    }

    private void setControlValue(Control control, String value)
    {
        if (control is ITextControl)
        {
            ITextControl txt = (ITextControl)control;
            txt.Text = value == null ? "" : value;
        }
        else if (control is ICheckBoxControl)
        {
            ICheckBoxControl chk = (ICheckBoxControl)control;
            chk.Checked = value != null;
        }
        else if (control is ListControl)
        {
            ListControl ddl = (ListControl)control;
            if (value == null)
                ddl.SelectedIndex = -1;
            else
                ddl.SelectedValue = value;
        }
    }

    public void saveForm()
    {
        saveControlRecursively(this._page);
    }

    private void saveControlRecursively(Control rootControl)
    {
        if (rootControl is IPostBackDataHandler)
        {
            var postBackData = _page.Request.Form[rootControl.ID];
            storage[_page.Request.Path][rootControl.ID] = postBackData;
        }

        if (rootControl.HasControls())
            foreach (Control subControl in rootControl.Controls)
                saveControlRecursively(subControl);
    }

    private static Control findControlRecursively(Control rootControl, String idToFind)
    {
        if (rootControl.ID == idToFind)
            return rootControl;

        foreach (Control subControl in rootControl.Controls)
        {
            Control controlToReturn = findControlRecursively(subControl, idToFind);
            if (controlToReturn != null)
            {
                return controlToReturn;
            }
        }
        return null;
    }
}

Вот примерная реализация на странице, которая перенаправляет на другую страницу:

private FormStorage storage;

protected void Page_PreInit(object sender, EventArgs e)
{
    storage = new FormStorage(this);
}

protected void BtnRedirect_Click(object sender, EventArgs e)
{
    Response.Redirect("RedirectForm.aspx");
}

Обратите внимание, что она загружается и сохраняется неявно на Page_Load/Page_PreRender,Поэтому экземпляр FormStorage должен быть создан в Page_PreInit.

Если вы хотите изменить значения после Page_Load программно, вам нужно вызвать storage.saveForm() вручную (например, в Page_PreRender), чтобычто эти значения переопределены, потому что FormStorage автоматически сохранит все данные обратной передачи в Page_Load.

Редактировать : Подход history.go к sh4nx0r, вероятно, лучше, так как он более масштабируем,Мой подход использует Session и не подходит для интернет-приложения с огромным количеством (возможных) пользователей.

Одно (небольшое) мое преимущество заключается в том, что оно будет работать, даже если JavaScript отключен.Еще одним преимуществом является то, что вы можете контролировать, на какую страницу вы хотите перенаправить.Вы даже можете восстановить значения для нескольких перенаправлений.

1 голос
/ 12 марта 2012

Вам не нужны сеансы, чтобы сделать это. Просто используйте JavaScript.

Предположим, у вас есть две страницы Page1.aspx и Page2.aspx. У вас есть текстовые поля, флажки, радиокнопки на Page1.aspx, и у вас есть кнопка «Отправить». Нажав на кнопку, вы перейдете к Page2.aspx.

Просто нажмите кнопку «Вернуться на предыдущую страницу» на Page2.aspx, которая при нажатии приведет вас к Page1.aspx со всеми этими значениями, которые все еще там. Для этого добавьте эту строку в событие Page2.aspx page_load

protected void Page_Load(object sender, EventArgs e)
{
 btnBackButton.Attributes.Add("onClick", "javascript:window.history.go(-1);return false;");
}
...