【ASP.NET MVC】【VB】ASP.NET MVCでknockout.js を使った際に ValidateAntiForgeryToken を使用する [1] ~試作版~

ASP.NET MVCでknockout.js を使った際に ValidateAntiForgeryToken を使用する

http://blogs.yahoo.co.jp/dk521123/35669223.html
をベースに、セキュリティ強化の一環で、ValidateAntiForgeryToken を使用するサンプルを考える。
ValidateAntiForgeryToken については、以下の関連記事を参照のこと。
http://blogs.yahoo.co.jp/dk521123/35641403.html

サンプル

http://stackoverflow.com/questions/2906754/how-can-i-supply-an-antiforgerytoken-when-posting-json-data-using-ajax
http://stackoverflow.com/questions/4074199/jquery-ajax-calls-and-the-html-antiforgerytoken
で記載されている方法で、とりあえず実装できた。
ただこれで本当にいいのかって疑問が残るが、ひとまず、記録として残しておく。

# 以下の関連記事に、決定版を記載しておく。
http://blogs.yahoo.co.jp/dk521123/35849982.html

モデル

* SampleKnockoutModel.vb
Namespace Models
    Public Class SampleCompanyModel
        Public Property CountryId As String
        Public Property CompanyNames As List(Of ListItem)
        Public Property CompanyIds As List(Of String)
    End Class
End Namespace

ビュー

* Index.vbhtml
@ModelType WebAppli.Models.SampleCompanyModel

@Code
    ViewData("Title") = "Index"
End Code

<h2>Index</h2><br />
@Using (Html.BeginForm(
                "SendResult",
                "SampleKnockout",
                FormMethod.Post,
                New With {.id = "comForm"}))
    @Html.AntiForgeryToken()
    @Html.RadioButtonFor(Function(model) model.CountryId, "JP")
    @Html.Label("Japan")@<br />
    @Html.RadioButtonFor(Function(model) model.CountryId, "US")
    @Html.Label("USA")@<br />
    @<select multiple="multiple" name="@Html.NameFor(Function(model) model.CompanyIds)"
             data-bind="options: items, optionsText: 'Text', optionsValue: 'Value'"
             size="7" width="200"></select>
            @<input type="submit" value="Send" />
End Using

<script src="@Url.Content("~/Scripts/jquery-1.10.2.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/knockout-3.4.0.debug.js")" type="text/javascript"></script>
<script type="text/javascript">
    function ViewModel() {
        var self = this;
        self.items = ko.observableArray();
    }

    var viewModel = new ViewModel();
    ko.applyBindings(viewModel);

    var token = $('input[name="__RequestVerificationToken"]').val();
    $('input[name="CountryId"]:radio').change(function () {
        $.ajax({
            type: 'POST',
            url: '@Url.Action("GetList")', // アクセス先のURL
            data: {
                __RequestVerificationToken: token,
                id: $(this).val(),
            },
        })
       .done(function (returnData) {
           viewModel.items(returnData.results);
       });
    });
</script>
* SendResult.vbhtml
@ModelType WebAppli.Models.SampleCompanyModel

@Code
    ViewData("Title") = "SendResult"
End Code

<h2>SendResult</h2>

<p>ID : @Model.CountryId </p>

@For Each companyId In Model.CompanyIds
    @<p>Company ID : @companyId</p>@<br />
Next

コントローラ

* CompanyController.vb
Imports System.Web.Mvc
Imports WebAppli.Models

Namespace Controllers
    Public Class CompanyController
        Inherits Controller

        Private CompanyInfoDictinary As Dictionary(Of String, List(Of ListItem))

        Public Sub New()
            CompanyInfoDictinary = New Dictionary(Of String, List(Of ListItem)) From
                {
                {"JP", New List(Of ListItem) From
                {
                New ListItem() With {.Value = "J01", .Text = "Sony"},
                New ListItem() With {.Value = "J02", .Text = "Hitachi"},
                New ListItem() With {.Value = "J03", .Text = "Toshiba"},
                New ListItem() With {.Value = "J04", .Text = "Fujitsu"}
            }
            },
                        {"US", New List(Of ListItem) From
            {
               New ListItem() With {.Value = "U01", .Text = "Google"},
               New ListItem() With {.Value = "U02", .Text = "Yahoo"},
               New ListItem() With {.Value = "U03", .Text = "Microsoft"}
            }
            }
            }
        End Sub

        Function Index() As ActionResult
            Dim model = New SampleCompanyModel()
            model.CountryId = "JP"
            Return View(model)
        End Function

        <ValidateAntiForgeryToken()>
        <HttpPost>
        Function GetList(ByVal id As String) As ActionResult
            Dim sendingValues = CompanyInfoDictinary(id)
            Return Json(New With {
                        .results = sendingValues},
                        JsonRequestBehavior.AllowGet)
        End Function

        Function SendResult(ByVal model As SampleCompanyModel) As ActionResult
            Return View(model)
        End Function

    End Class
End Namespace

関連記事

ASP.NET MVCでknockout.js を使った際に ValidateAntiForgeryToken を使用する [2] ~決定版~

http://blogs.yahoo.co.jp/dk521123/35849982.html

ASP.NET MVCAjax通信時にValidateAntiForgeryToken を使用する

http://blogs.yahoo.co.jp/dk521123/35813912.html

ASP.NET MVC で、 knockout.js を使う ~基本編~ [1]

http://blogs.yahoo.co.jp/dk521123/35669223.html

Html.AntiForgeryToken() / ValidateAntiForgeryToken

http://blogs.yahoo.co.jp/dk521123/35641403.html