久々にVBとWebFormsをいじる用事があったので書き留めました。
ページをロードするときに、formのactionを書き換えようって話です。
環境は
VS2013、.net framework4.5
VB、ASP.NET WebForms
です。
方法としては、
- Page_Loadの動作時に、なんらかの条件をもとに、指定のformのactionを書き換える。
- jsonで、キーとなる値とそのactionとなる値を持っておき、キーが条件とマッチするactionに書き換える。
って感じです。
jsonさんは、簡易なリストを作って、プロジェクトの直下においておきました。
[ { "Ip": "ip1", "Action": "http://www.msn.com/ja-jp" }, { "Ip": "ip2", "Action": "http://www.yahoo.co.jp/" }, { "Ip": "ip3", "Action": "http://www.microsoftvirtualacademy.com/" } ]
適当なWebページ(今回は、DynamicAction.aspxとします)というWebページをプロジェクト直下に追加します。
そのページにデフォルトで生成されたformタグにsubmitするボタンつけただけです。コードビハインドでタグのidを呼べるようにするには、タグのattributeに「runat="server"」つけておくのはポイントです。(今回のサンプルはデフォルトでついてますけど...)
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="DynamicAction.aspx.vb" Inherits="VB_webforms_demo01.DynamicAction" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> </head> <body> <form id="form1" action="http://www.asp.net/" runat="server"> <div> </div> <input type="submit" value="submit" /> </form> </body> </html>
Jsonの処理は、みんな大好きJson.NETを使います。Nugetからインストールしておきます。
JsonのDeserializeしたものを格納するのに、ActionMapというクラスを用意しました。
条件とマッチングさせるキーとなるプロパティを「Ip」、actionは「Action」プロパティを用意しました。
実際に格納するのは、ActionMapのListにします。
Class ActionMap Public Property Ip As String Public Property Action As String End Class
今回は、
ActionMapのクラスも、Jsonを処理するメソッドも、Webページのコードビハインド、DynamicAction.aspx.vbに書いちゃいました。
Jsonの処理なんて、多少真面目に書くときは、Helperみたなクラス作ってpublicでstaticな(あ、VBだとSharedか)のにすべきですかね。
で、Genericsで...とかでしょうね。
ということで、DynamicAction.aspx.vbには、まずnamespaceをインポートしておきます。
Imports Newtonsoft.Json Imports System.IO
Jsonファイルから値取得して、ActionMapのListにする処理のメソッドをこんな感じで...。
Private Sub CreateActionMapListFromJson() Using reader As New StreamReader(Server.MapPath("actionMap.json")) Dim serializer = New JsonSerializer actionMapList = serializer.Deserialize(reader, GetType(List(Of ActionMap))) End Using End Sub
serializer.Deserializeの戻り値になるactionMapList は、DynamicAction.aspx.vbのメンバー変数として宣言してます(諸事情により)。
Private actionMapList As List(Of ActionMap)
C#で書いてるときは、json.netのサンプルの通りにserialize.Deserializeのときに明示的にキャストしてるんですが、今回のサンプルでは、...(ry
必要あるのかなーとか内心思ってますが、なーんも考えてません...
余談ですが、久々にVBやると、C#のtypeofのノリでVBでもtypeof使ったら怒られて、なんか笑えました...
VBだと、GetTypeですね。
さて、本題のPage_Loadの処理です。
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load CreateActionMapListFromJson() '今回はとりあえず、こんな条件 Dim targetIp = Request.Url.ToString Dim action = actionMapList. Where(Function(n) n.Ip = targetIp). Select(Function(n) n.Action). FirstOrDefault If (Not IsNothing(action)) Then form1.Action = action End Sub
Jsonの処理メソッドを呼んで、Jsonファイルから取得した値をActionMapのListをメンバー変数に入れます。
とある指定の条件(変数:targetIp)が、ListのActionMapクラスのIpプロパティとイコールだったら、そのActionプロパティを取得するという処理にしています。
とある指定の条件は適当につくりました(諸事情によりこれ)。
条件とマッチしたものがあれば、取得したActionプロパティの値をform1のactionの値として書き換えます。マッチするのがなければ、aspxに書いたactionをそのまま実行です。
ラムダ式が使えない事情の場合は、foreachとかでゴリゴリしましょう。(諸事情により...)
jsonが諸事情でアレでしたら、XMLで同じことすればいいかなーとか。(諸事...(ry
ってか、VBのラムダ式の方が先におぼえたのにもう完全に忘れてる。C#のノリでアローを書いてエラーになってこうなりました。
というかC#と違いすぎて、不思議と笑えました...。