web-dev-qa-db-ja.com

ASP.NETマスターページとコンテンツページのフォーム要素

わかりました、私の現在のプロジェクトの別のバンプです。

bothのマスターページとコンテンツページにフォーム要素を配置したことがないので、関連するすべてのフォームをコンテンツに含める傾向があります。

ただし、現在のプロジェクトでは、両方が必要なページがあります。 右上のログインフォームとコンテンツの質問フォーム

これを実現するために、マスターページに単一のフォーム要素が必要であるというASP.NETのうめき声に遭遇しました。 TBH、これがASP.NETの要件である理由はわかりませんが、ほら。

マスターページとコンテンツページに独立して機能するフォーム要素を含めることができるかどうか/方法を誰かが知っていますか?

そうでない場合、希望の外観/機能を取得するための手順についてアドバイスを提供できますか?

24
Rob Cooper

私は私の未解決の質問のいくつかを確認し、それらのいくつかを締めくくることができるかどうかを確認すると思いました。

これは面白いものでした。 ASP.NETページでフォームを1つだけ持つことができるとは信じません。これは私には意味がありませんでした。 Webページに複数のフォームがあるWebページをたくさん見ましたASP.NETページはなぜ違うのですか?

だから、考えさせられました。

ASP.NETページがフォーム要素を必要とするのはなぜですか?

ASP.NETページは、PostBackモデルを通じて状態の永続性を提供することにより、WinForms環境をエミュレートしようとします。これは、ステートレス環境に状態の要素を提供します。これを行うには、ランタイムが各「フォーム」内でこの状態を維持できる必要があります。これは、データをそれ自体にポストバックすることによって行われます。次のことに注意することが重要です。

  • PostBackについて、それほど凝ったものはありません。
  • 他のスタックと同じように、HTTPフォームとPOSTを使用します。
  • 何か特別なことをしているように見えるかもしれないからといって、そうではありません。POSTが原因の情報を返し、サーバー側のコードでクライアント側のイベントを処理するなどのことができるのです。

では、なぜ1つだけなのでしょうか。

これは、100万ポンドの質問でした(私はイギリス人です)。特にASP.NETサーバーコントロールを使用している場合、ASP.NETがこれを必要とすることを理解していますが、なぜ私は独自の追加フォームを作成できないのですか?

だから、ねじ込むと思って、自分だけの形にしよう!

そして私はしました。 "#"の送信アクションを備えた、沼地標準のシンプルなフォームを追加しました。次に、現在のページに対してPOSTを実行し、リクエスト内の指定されたフォームのフォームデータを使用します。

何だと思う?それはすべてうまくいきました。だから私は結局:

  • HTMLフォームを含むマスターページ
  • このフォームは現在のページ(基本的にはマスターを使用するページ)にポストバックします。
  • 次に、マスターのPage_Loadコードビハインドで、リクエストをチェックしてリクエストで渡されたデータを確認するコードを追加しました。データが含まれている場合(非表示フィールドなど)、投稿がマスターページのフォームから提供されていることを知っています。そうでない場合は、おそらくコンテンツからのPostBackであり、無視できます。
  • 次に、Contentタグを<form runat="server" id="aspNetForm"...> </form>タグで囲みました。これは、すべてのコンテンツページが自動的に操作するフォームを持つことを意味しました。

これにより、問題に対する比較的単純でクリーンな解決策が得られました。私のログインフォームは、作成されたすべてのコンテンツフォームと連携して問題なく機能します。その中には、複雑なフォームもあれば、多くのサーバーコントロールや多くのポストバックを使用するものもあります。

これが他の人の役に立つことを願っています。

19
Rob Cooper

フォームタグ自体はMasterPage内にあるため、任意のasp.netサーバーコントロールを必要なマスターページにコーディングできます。また、これらのサーバーコントロールの処理ロジックを、マスターページの分離コードファイルに書き込むことができます。

そのため、この例では、マスターページの右上にログインコントロールを配置し、コンテンツページではなく、マスターページのコードページに認証ロジックを配置できます。

これにより、すべてのページにログインコントロールを配置し、その処理を維持するだけでなく、個々のページでコンテンツコントロールとその処理を維持できます。

5

ロブ、

興味深いソリューション。私はあなたがしていることに問題はないと思います。ただし、一部のユーザーが遭遇する可能性がある問題は、2つのサーバーフォームでこれを実行しようとした場合です。 ASP.NETには、1つのページに複数のHTMLフォームを含めることはできません。ページに複数の "runat = 'server'"フォームを含めることはできません。明らかに、ニーズを満たす非常に簡単な方法を見つけました。

ASP.NETフレームワークは基本的にすべてのものを名前付けコンテナーで分離するため、単一のフォームを処理することはほとんど問題ではないことがわかりました。しかし、最初の投稿コメントでは、欠落していたが、元の質問の本質にとって重要であった重要な要素にぶつかりました。重要な動作を入力してください。それは常にモンキーレンチを作品に投げ込みます。

標準の「すべてを網羅する」サーバーフォームを使用する場合、テキストボックスのテキスト変更イベントを使用して適切なアクションをキャプチャできませんでしたか?もちろん、ユーザーがどちらかでEnterキーを押す前に両方の値を変更すると、奇妙な動作が発生します。また、Enterキーの主な問題は、HTMLフォームで複数の送信入力があると、テキストボックスでEnterキーを押しても何も実行されないことです。単一のINPUT要素がある場合にのみ、Enterキーを押すと、要素が「クリック」されます。

4
Peter

他の誰もが、特定のASP.NETページではフォーム要素を1つしか持つことができず、マスターページに含まれることをすでに述べています。ここまでは順調ですね。しかし、それがあなたがなりたい場所に完全に到達するのを助けるとは思わない...

マスターページでは、(おそらく)asp:ContentPlaceHolderコントロールを定義しました。マスターを使用するページには、対応するasp:Contentタグがあります。すべてのページコンテンツは、これらの対応するasp:Contentタグで囲む必要があります。

そのタグに入ると、それらはマスターページのフォームの一部になります。マスターページは、独自のコントロールからのイベントに応答でき、ページ自体が独自のコントロールからのイベントに応答するので、設定は完了です。

マスターページとやり取りするページが必要な場合は、Page.Masterプロパティを介してアクセスできます。マスターページから公開されているコード(メソッド、プロパティなど)を操作するには、このプロパティを正しい型にキャストし、そこから公開されているコードにアクセスします。

これで、このシナリオで必要な場所が得られます。 (それは私のために複数のサイトで働いています!)

4
John Rudy

上記の回答のいずれもコード例を示していません。これは、これを行う方法を示すVisual Studio 2012 Site.Masterの簡易バージョンです。

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site - Copy.Master.cs" Inherits="WebApplication1.Site1Master" %>
<!DOCTYPE html>
<html>
    <head runat="server">
        <title>This is a title</title>
        <asp:ContentPlaceHolder runat="server" ID="HeadContent" />
    </head>
    <body>
    <form runat="server">
    <header>
        <div class="content-wrapper">
            <div class="float-right">
                <section id="login">
                    <asp:LoginView runat="server" ViewStateMode="Disabled">
                        <AnonymousTemplate>
                             <asp:ContentPlaceHolder runat="server" ID="AnonContent" />
                        </AnonymousTemplate>
                        <LoggedInTemplate>
                            <asp:ContentPlaceHolder runat="server" ID="LoggedInContent" />
                        </LoggedInTemplate>
                    </asp:LoginView>
                </section>
            </div>
        </div>
    </header>
        <div id="body">
        <asp:ContentPlaceHolder runat="server" ID="FeaturedContent" />
        <section class="content-wrapper main-content clear-fix">
            <asp:ContentPlaceHolder runat="server" ID="MainContent" />
        </section>
    </div>
    </form>
</body>
</html>

したがって、すべてが単一のForm要素でラップされているので、マスターページにコントロールを配置でき、コンテンツページでもコントロールを使用できます。

3
John Saunders

ASP.NETページではフォームを1つだけ持つことができます。これを処理する1つの方法は、マスターページのログインボタンにイベントハンドラーを配置することです。ハンドラーはユーザーを検証し、成功すると同じページにリダイレクトします(イベントハンドラーの前に実行されるPage_Loadハンドラーを正しく実行するため)。

2
Dan Goldstein

現在のプロジェクトで「ログインサブフォームのリターンキーをクリックするとメインフォームが送信される」という問題をマスターページにiframeを埋め込むことで解決しました。 iframeは、ユーザーを認証したlogin.aspxページを指しています。

<iframe id="login" src="login.aspx" frameborder="0" enableviewstate="false" scrolling="no" runat="server"></iframe>

(何らかの理由で/ iframeの終了タグが必要でした。そうしないと、デザインビューが混乱しました)

0
Steve Davies

軟膏!同様のスレッドで、私はあなたを助けるかもしれない答えを投稿しました。 jqueryを使用して、空のdivにコンテンツを追加できます。そのコンテンツにはフォームタグを含めることができ、サーバー側のコードが実行していることに依存しない送信関数を含めることもできます。これの唯一の欠点は、ユーザーがJavaScriptを有効にしていない場合です。

同じ回答(およびコードも)を再投稿する代わりに、リンクは次のとおりです。

asp.net webform上のJquery Ajaxロードフォーム

0
bgmCoder

これはASP.NETの制限です

ASP.NETは、ページごとに1つのフォームと1つのフォームのみを持つように設計されています。それが最初に設計されたとき、それは問題ではありませんでした。

しかし、それ以来、これはアクセシビリティに関する大きな問題として認識されてきました。

これに対するMicrosoft FixはASP.NET MVCでした。ASP.NETに関する多くの問題を解決するため、ASP.NET MVCへの移行を検討することをお勧めします。

0
Kevin Damen