4

私は次のコードを持っています:

protected void gv_inbox_RowCommand(object sender, GridViewCommandEventArgs e)
{
    int index = Convert.ToInt32(e.CommandArgument);

    if (e.CommandName == "sign")
    {
        Session["TransYear"] = int.Parse(((HiddenField)gv_inbox.Rows[index].Cells[1].FindControl("HDN_TransYear")).Value);
        Session["MailNumber"] = int.Parse(((HiddenField)gv_inbox.Rows[index].Cells[1].FindControl("HDN_MailNumber")).Value);
        Response.Redirect("Signature.aspx", false);
        //Response.Write("<script>");
        //Response.Write("window.open('Signature.aspx','_blank')");
        //Response.Write("</script>");
    }
}

ページを新しいタブまたはウィンドウで開きたい。コメント付きのコードはそれを行いますがrefresh、元のページでエラーが発生した場合.how to open Signature.aspxa new window or tab in a right way in a row command event of my gridview .

4

6 に答える 6

5

やりたいことは、 を使用しScriptManagerて JavaScript 呼び出しを行うことです。

定義した JavaScript スニペットは機能しますが、ScriptManager実行には が必要です。

String js = "window.open('Signature.aspx', '_blank');";
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "Open Signature.aspx", js, true);

を使用Response.Writeする際の問題はPostBack、ブラウザがスクリプト タグを実行しないことです。一方、 を使用するScriptManager.RegisterClientScriptBlockと、ASP.NETScriptManagerがコードを自動的に実行します。

更新 - 2013/02/14

Vladislav's answerで示唆されているように、 ClientScriptvs .を使用しScriptManagerます。違いはClientScript同期ポストバックのみ ( no asp:UpdatePanel) とScriptManager、非同期ポストバック ( を使用asp:UpdatePanel) です。

asp:GridViewさらに、以下の著者のコメントによると、 をで囲むとasp:UpdatePanel、更新を確認するブラウザ メッセージが表示されなくなります。同期ポストバック (no asp:UpdatePanel) の後でページを更新すると、ブラウザーは最後のコマンドを再送信し、サーバーは同じプロセスをもう一度実行します。

最後に、 をasp:UpdatePanelと組み合わせて使用​​する場合ScriptManager.RegisterClientScriptBlockは、最初と 2 番目のパラメータを必ずasp:UpdatePanelオブジェクトに更新してください。

ScriptManager.RegisterClientScriptBlock(updatePanel1, updatePanel1.GetType(), "Open Signature.aspx", js, true);
于 2013-02-13T20:55:38.270 に答える
4

まず、ここでの演習は、あるページから別のページに単純な値を渡す方法です。

あなたの場合、それらはキー/値のみであるため、GETを介して渡すことができます。

コマンドボタンではなく、これをすべての行にレンダリングする必要があります。

<a href="Signature.aspx?TransYear=value1&MailNumber=value2" target="_blank">
    Sign
</a>

この例では、value1とvalue2は、それぞれHDN_TransYearとHDN_MailNumberに書き込んでいた値です。

Signature.aspxでは、セッション変数を使用する場合は、次のような操作を行う必要がありました。

Session["TransYear"]
Session["MailNumber"]

これで、次のように変更する必要があります。

Request.QueryString["TransYear"]
Request.QueryString["MailNumber"]

それは通常あなたが求めたものになります。だが...

このメソッドが安全でないと言う場合は、パラメータ値を変更することで、誰でもクエリ文字列変数を操作できます。

各行の署名を計算し、この署名をクエリ文字列の3番目のパラメータとして配置し、反対側の値と署名を検証します。

署名を計算する方法は、まあ、それはあなた次第です。それがあなたの秘密のソースです。ハッシュ関数とソルティングアルゴリズムはたくさんあります。

非常に簡単な例として:

string signature = CRC32(HDN_TransYear + "stuff that you only know" + HDN_MailNumber)

次に、リンクは次のようになります。

<a href="Signature.aspx?TransYear=2012&MailNumber=1&sig=8d708768" target="_blank">
    Sign
</a>

Signature.aspxでは、クエリ文字列の値と「知っているもの」を使用して、CRC32署名を再度計算し、クエリ文字列のパラメータとして渡された署名に対して検証します。

ドラマはありません。

于 2013-02-19T17:00:42.877 に答える
2

次のコードは、何年も前からうまく使用されています。これらのいくつかのメソッドは、より大きな汎用モジュールから抽出されていますが、すべてを含めたと思います...

public class Utilities
{
    /// <summary>
    /// This will return the first parent of the control that is an update panel
    /// </summary>
    /// <param name="source">The source control</param>
    /// <returns>The first parent found for the control. Null otherwise</returns>
    public static UpdatePanel GetFirstParentUpdatePanel(Control source)
    {
        Page currentPage = source.Page;
        UpdatePanel updatePanel = null;
        Type updatePanelType = typeof(UpdatePanel);
        object test = source.Parent;
        while (test != null && test != currentPage)
        {
            // is this an update panel
            if (test.GetType().FullName == updatePanelType.FullName)
            {
                // we've found the containing UpdatePanel
                updatePanel = (UpdatePanel)test;
            }

            // check the next parent
            test = ((Control)test).Parent;
        } // next test

        return updatePanel;
    }

    /// <summary>
    /// This will open the specified url in a new window by injecting a small script in
    /// the current page that is run when the page is sent to the client's browser.
    /// This method accounts for the presence of update panels and script managers on the
    /// page that the control resides in.
    /// </summary>
    /// <param name="source">The control that the call is being made from</param>
    /// <param name="url">The URL to bring up in a new window</param>
    public static void RedirectToNewWindow(Control source, string url)
    {
        // create the script to register
        string scriptKey = "_NewWindow";
        string script = "window.open('" + url + "');";
        RegisterControlScript(source, scriptKey, script);
    }

    /// <summary>
    /// This will register a script for a specific control accounting for the control's UpdatePanel
    /// and whether or not there is a script manager on the page
    /// </summary>
    /// <param name="source">The control that will be affected by the script</param>
    /// <param name="scriptKey">A unique key for the script</param>
    /// <param name="script">The script that will affect the control</param>
    public static void RegisterControlScript(Control source, string scriptKey, string script)
    {
        // get the control's page
        Page currentPage = source.Page;

        // does the control reside in an UpdatePanel
        UpdatePanel updatePanel = GetFirstParentUpdatePanel(source);

        // did we find the UpdatePanel
        if (updatePanel == null)
        {
            // register the script on the page (works outside the control being in an update panel)
            currentPage.ClientScript.RegisterStartupScript(currentPage.GetType(), scriptKey,
                                                           script, true /*addScriptTags*/);
        }
        else
        {
            // register the script with the UpdatePanel and ScriptManger
            ScriptManager.RegisterClientScriptBlock(source, source.GetType(), scriptKey,
                                                    script, true /*addScriptTags*/);
        } // did we find the UpdatePanel
    }
}

次に、あなたの使用法のために、あなたは電話します

protected void gv_inbox_RowCommand(object sender, GridViewCommandEventArgs e)
{
    int index = Convert.ToInt32(e.CommandArgument);

    if (e.CommandName == "sign")
    {
        Session["TransYear"] = int.Parse(((HiddenField)gv_inbox.Rows[index].Cells[1].FindControl("HDN_TransYear")).Value);
        Session["MailNumber"] = int.Parse(((HiddenField)gv_inbox.Rows[index].Cells[1].FindControl("HDN_MailNumber")).Value);
        Utilities.RedirectToNewWindow(gv_inbox, "Signature.aspx");
    }
}

これらのヘルパー メソッドを抽出したので、最も簡潔なコードではありませんが、アイデアはわかります。上記のコードは c#2.0 以降で動作し、UpdatePanelネストに関係なく、またはUpdatePanels がまったく使用されていなくても動作します。

于 2013-02-18T17:49:56.833 に答える
2

ClientScript.RegisterStartupScript(this.GetType(), "Open Signature.aspx", js, true); ページを更新する必要はありません。 スクリプト ブロックは、ページがポストバックから回復した後に起動します。

そして、単なる提案: - あなたの場合、DataKeys を使用して、HiddenFields を使用する代わりに TransYear と MailNumber の値を取得することは可能ですか?

于 2013-02-14T12:53:16.507 に答える
2

新しいウィンドウを開く前にセッションを設定するのはなぜですか?

@Davidが指摘したように、必要なパラメーターがクエリ文字列として渡されていることを考えると、新しいウィンドウを開いたにセッションを設定しても問題ない場合は、のコードビハインドで実行できると思います。Signature.aspx

于 2013-02-19T02:42:32.470 に答える