複数のページからPostBackUrlで遷移したい時

この記事は、One ASP.NET Advent Calendar 2013の22日目の記事です。

前回はTAKANO Sho / @masaru_b_clさんのASP.NET Friendly URLsを使う #aspnetjp by @masaru_b_clでした。

で、怒涛の連続投稿ですが全てはこの記事のための伏線でした。

前回はPostBackUrlでの値の受け渡しについて紹介しましたが、今回は複数のページからPostBackUrlで遷移したときの値の取得の仕方についてです。

PreviousPageTypeは複数指定できない

遷移先のaspxにPreviousPageTypeを2つ追加してもコンパイルエラーは起きません。

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Result.aspx.vb" Inherits="PostBackUrlMulti.Result" %>

<%@ PreviousPageType VirtualPath="~/Input1.aspx" %>
<%@ PreviousPageType VirtualPath="~/Input2.aspx" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <asp:Label ID="LblResult" runat="server" />
        </form>
    </body>
</html>

が、実際に起動してみて遷移先のページに遷移するとエラーになります。

PreviousPageTypeは一つしか指定できないようです。

そもそもaspxに2つPreviousPageTypeを書いても、designerファイルには1つしか登録されていません。

Public Shadows ReadOnly Property PreviousPage() As PostBackUrlMulti.Input2
    Get
        Return CType(MyBase.PreviousPage, PostBackUrlMulti.Input2)
    End Get
End Property

後に書いたほうで上書きされるようです。

解決策

遷移先の画面でインターフェースを決定してしまえば、複数の画面からPostBackUrlで遷移してきても対応できます。

まずは下記のようにInterfaceを作成します。

Public Interface IResult

    ''' <summary>
    ''' 受け渡しする値を格納するプロパティ
    ''' </summary>
    ''' <remarks></remarks>
    ReadOnly Property TxtInputValue As String

End Interface

次に遷移元となるページで上記のInterfaceを実装し、プロパティに遷移先に渡したい値をセットします。

Public Class Input1
    Inherits System.Web.UI.Page
    Implements IResult

    ''' <summary>
    ''' Interfaceの実装時にできたプロパティ。
    ''' PostBackUrlで遷移したページに値を渡す。
    ''' </summary>
    ''' <remarks></remarks>
    Public ReadOnly Property TxtInputValue As String Implements IResult.TxtInputValue
        Get
            Return Me.TxtInput.Text
        End Get
    End Property

End Class
Public Class Input2
    Inherits System.Web.UI.Page
    Implements IResult

    ''' <summary>
    ''' Interfaceの実装時にできたプロパティ。
    ''' PostBackUrlで遷移したページに値を渡す。
    ''' </summary>
    ''' <remarks></remarks>
    Public ReadOnly Property TxtInputValue As String Implements IResult.TxtInputValue
        Get
            Return Me.TxtInput.Text
        End Get
    End Property

End Class

遷移先のページではaspxからPreviousPageTypeを削除し、PageクラスのPreviousPageをInterfaceにキャストして返すようにプロパティを追加します。

Public Class Result
    Inherits System.Web.UI.Page

    ''' <summary>
    ''' 遷移元のページ
    ''' </summary>
    ''' <remarks></remarks>
    Public Shadows ReadOnly Property PreviousPage() As IResult
        Get
            Return CType(MyBase.PreviousPage, IResult)
        End Get
    End Property

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        ' 遷移元のページの値を表示する
        Me.LblResult.Text = PreviousPage.TxtInputValue
    End Sub

End Class

こうすることでInput1.aspxとInput2.aspxからPostBackUrlで遷移したときに、両方のページから値を取得することが出来ます。

ただ、Interfaceを実装していないページから遷移してきたときはエラーになるのでCTypeでキャストせずにTryCastでキャスト後、Nothingならほげもげ、という処理を書く必要があります。

そもそもPostBackUrlでの遷移自体あまりオススメされてないようなので、POSTでページ遷移したいならおとなしくASP.NET MVCを導入したほうがいいかもしれません。

まとめ

ということでもう誰も使ってないんじゃないかというくらいWeb Formsのレガシーな記事でしたが、もし来年もOne ASP.NET Advent Calendarがあるようならば新しめな技術の記事を書きたいですなー、と思います。

ということで明日は謎社CTOのneueccさんがブッチ切りの最新技術について書いてくれると思いますよ!!

乞うご期待!!

カテゴリー: .NET, ASP.NET, VB, Web Forms パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>