Почему бы не реализовать IsRefresh, IsBackPost, как IsPostBack? - PullRequest
2 голосов
/ 16 февраля 2010

Я мог видеть, что у меня самого и многих людей возникают проблемы с этими двумя элементами в ASP.NET ... Кнопка "Обновить", Кнопка "Назад" ... (Я вижу, что многие люди задавались вопросом, как отключить эти две кнопки в браузере ..)

Теперь, каковы проблемы в реализации еще двух логических переменных в Page (IsRefresh, IsPostBack) ... Если эти проблемы можно обойти и реализовать, это было бы большим преимуществом для разработчиков ...

Когда вы отвечаете, не могли бы вы также включить шаги, которые вы предпринимаете в своем веб-приложении, чтобы избежать повторного размещения (иногда в БД) в таких сценариях, которые будут полезны.

Спасибо

Ответы [ 3 ]

5 голосов
/ 16 февраля 2010

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

  1. отображать страницу из кэша, если это разрешено, или
  2. снова выполнить тот же запрос (возможно, сначала попросив пользователя подтвердить)

У вас дело № 2. Когда происходит второй запрос, сервер получит точные те же данные запроса, что и при исходном запросе. Таким образом, ASP.NET (и большинство других сред) будет обрабатывать запрос так же, как обрабатывался оригинал. Есть несколько способов обойти эту проблему:

  1. Измените политику кэширования, чтобы браузер мог отображать результаты предыдущих запросов (может решить проблему Назад , но не Обновить ).
  2. Добавить скрытое поле (или данные в ViewState), содержащее уникальное значение на странице, откуда ожидаются обратные передачи. Затем добавьте некоторую структуру данных, чтобы сохранить список «используемых» значений, а также логику для проверки на наличие дубликатов, прежде чем делать что-либо критическое.
  3. Используйте шаблон Post / Redirect / Get , чтобы запрос POST никогда не попадал в историю браузера.

Решение № 3 очень просто и работает почти во всех случаях. По сути, вместо того, чтобы возвращать результаты / подтверждение в качестве ответа на «критическую» обратную передачу, сделайте перенаправление на новый URL:

protected void btnCritical_Click(object sender, EventArgs e)
{
    DoSomethingThatShouldNotBeDoneTwice();
    Response.Redirect("confirmation.aspx");
}
1 голос
/ 16 февраля 2010

aspnet_isapi распознает обратную передачу по содержимому формы, в частности по полю ViewState. У него нет встроенного способа отличить постбэк от обновления.

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

Вы можете создать базовую страницу, от которой наследуются все ваши страницы.

public partial class PageBase : System.Web.UI.Page
{
    private Guid _requestId;

    protected Guid RequestId
    {
        get
        {
            return _requestId;
        }   
    }
    protected virtual void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            _requestId = Guid.NewGuid();
            ViewState.Add("requestId", _requestId);
        }
        else
        {
            _requestId = (Guid)ViewState["requestId"];
        }
    }
}

public partial class _Default : PageBase
{
    protected override void Page_Load(object sender, EventArgs e)
    {
        base.Page_Load(sender, e);

        // now do stuff
    }
}
1 голос
/ 16 февраля 2010

Это не совсем так ясно. Единственный способ, которым сервер может идентифицировать «PostBack», основан на заголовках, переданных странице по вашему запросу. Когда вы размещаете форму, «IsPostBack» является истинным, как и следовало ожидать. Когда вы обновляете страницу или нажимаете Назад, отправляются точно такие же данные запроса. Приложение не может обнаружить, что пользователь выполнил нестандартный запрос (Назад или Обновить), не изменив поведение браузера, отправляющего запрос.

Как вы знаете, большинство браузеров сообщают вам, что «Нажатие кнопки« Назад »отправит данные формы ...», но это всего лишь предупреждение, выдаваемое браузером, чтобы вы знали, что он отправит точно такой же запрос снова. Сервер не знает этого и не имеет (собственного) способа интерпретации информации.

Советы по предотвращению двойной обратной передачи

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

При каждой загрузке страницы вы хотите создать уникальный идентификатор для событий PostBack этой страницы. Не имеет значения, что представляет собой уникальный идентификатор, если он не совпадает при последовательной загрузке страницы. Поместите этот уникальный идентификатор в скрытое поле на своей странице И в сеансе пользователя (или в файле cookie). Затем на каждом PostBack проверяют, что cookie в скрытом поле соответствует значению в сеансе. Если значения совпадают, PostBack - это оригинальное сообщение на странице, которое может быть обработано соответствующим образом. После выполнения необходимых операций вам нужно будет снова изменить уникальный идентификатор в обоих местах. Таким образом, если пользователь должен нанести ответный удар и выбрать «Переслать данные», скрытое поле не будет соответствовать ключу сеанса, и вы можете выбросить дубликаты данных публикации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...