6

Form 要素 ( ) を含むマスター ページ<form runat="server">、Button 要素 ( <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Sync" />) を含むコンテンツ ページ、および関数を含むコード ビハインド ページがありButton1_Clickます。

ユーザーがページに来て、ボタンをクリックします。コード ビハインド コードが (サーバー上で) 実行され、データベース内のいくつかのテーブルが更新されます。コード ビハインド コードが最後に行うことはInnerHTML、成功または失敗のメッセージを含むコンテンツ ページの Span 要素の を設定することです。

それはすべてうまくいきます。問題は、ユーザーがページを更新すると、フォームが再送信され、ブラウザがそれが本当にユーザーが望んでいるものかどうかを尋ねることです。ユーザーが肯定的に応答すると、Code Behind コードが再実行され、データベースが再度更新されます。ユーザーが否定的に応答した場合、何も起こりません。

Code Behind コードを再実行することは大したことではありません。それは何も傷つけません。しかし、それは私が本当に望んでいる動作ではありません。

Response.Redirect() を使用してページにリダイレクトできることはわかっていますが、ユーザーには成功または失敗のメッセージが表示されません。メッセージは実際には「成功」または「失敗」以上のものであることに言及する必要があります。それ以外の場合は、リダイレクトの QueryString に何かを追加できると思います。

コード ビハインド コードからフォーム要素をリセットして、ユーザーがページを更新した場合にフォームが再送信されないようにする方法はありますか?

マスターページは...

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="IntuitSync.SiteMaster" %>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:ipp="">
    <head runat="server">
    </head>
    <body>
        <form runat="server">
            <div runat="server" id="mainContetntDiv">
                <asp:ContentPlaceHolder ID="MainContent" runat="server" />
            </div>
        </form>
    </body>
</html>

コンテンツ...

<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/Site.master" CodeBehind="SyncToCloud.aspx.cs" Inherits="IntuitSync.SyncToCloud" %>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Sync" />
    <span runat="server" id="SyncStatus"></span>
</asp:Content>

コードビハインド...

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;
using System.Web;

namespace IntuitSync
{
    public partial class SyncToCloud : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            /*
                Do a bunch of stuff and put the results in syncResults which is a List.
            */
            SyncStatus.InnerHtml = string.Join("", syncResults.ToArray()); // I'd rather do this...
            //Response.Redirect(Request.Url.PathAndQuery, true);  // ...and not do this.
        }
    }
}

どんな助けでも大歓迎です。

4

2 に答える 2

8

問題は、ユーザーが後でページを更新した場合に、フォーム POST を実行していることです。つまり、POST を再送信します。それを回避する方法はありません。したがって、利用可能なオプションは次のとおりです。

  1. 確認ページにリダイレクトし、何らかの方法で操作結果を確認ページに渡します (通常、クエリ文字列/Cookie などで実行できない場合は、データ リポジトリから再読み込みします)。
  2. 同じページにリダイレクトしますが、クエリ文字列パラメーターを介して成功メッセージを渡します (または、ばかげて、session/ViewState/what-have-you-silliness に保存します)。
  3. 投稿する代わりに、値を投稿していないように見えるため、フォーム取得を実行し、何らかのサーバー側の処理を開始するだけです。これを行うには、フォームを投稿から取得に変更するか、リンクを行うだけです。ここでの危険は、get 操作で変換的/破壊的な操作を行うべきではないということです。

:すべてのユーザー入力を必ずサニタイズしてください(ユーザー入力を常に悪として扱います)。

おそらく最後のオプションで最も満足するでしょうが、それはすべて、「たくさんのことを行い、その結果をsyncResultsに入れる...」が実際に何を伴うかによって異なります。

更新(数年後)

明らかなはずですが、一部のユーザーにとっては十分に明白ではない場合があります。サニタイズされていない「クエリ文字列パラメーターを介した成功メッセージ」を直接表示して、XSS 攻撃にさらされることは決してありません。提案はこれが明白であると想定していましたが、振り返ってみると、その点で明確に明確である必要がありました。

于 2013-02-07T22:07:33.083 に答える