xVal バージョン1.0 がリリースされました。

xVal
http://xval.codeplex.com/

xVal v1.0 Now Available
http://blog.codeville.net/2009/09/17/xval-v10-now-available/

 

ASP.NET MVC でバリデーションを行うとき、同じ定義をサーバーサイドとクライアントサイドの両方記述する必要がありましたが、xVal を使うと1カ所にまとめられます。

demo project を参考にしながら、ASP.NET MVC でサーバーサイドを DataAnnotations 、クライアントサイドに jQuery Validation を使って簡単に試してみます。

ASP.NET MVC プロジェクトでデフォルトで作成される Home の Index.aspx に 入力フォームを設置し、エラーがなければ Aboutにリダイレクトする手抜きな実装です。

環境:Windows 7, .NET Framework 3.5, ASP.NET MVC 1.0, xVal 1.0

 

1.ファイルのダウンロード

xValjQuery Validation をダウンロードします。

 

2.ASP.NET MVC プロジェクトを作成し、xVal.jquery.validate.js と jquery.validate.js を Scripts フォルダにコピーし、xVal.dll と System.ComponentModel.DataAnnotations を参照に追加します。

 

3.今回使用する Module, View, Controllerを作成又は修正します。

Module :  Person クラスを作成します。

using System.Linq;
using System.ComponentModel.DataAnnotations;
using xVal.ServerSide;
using xValTest.Helpers;

namespace xValTest.Models
{
    public class Person
    {
        [Required(ErrorMessage = "名前を入力してください。")]
        [StringLength(50, ErrorMessage = "名前が50文字を超えています。長すぎませんか?")]
        public string Name { get; set; }

        [Required(ErrorMessage = "年齢を入力してください。")]
        [Range(0, 100, ErrorMessage = "100歳までしか対応してません。")]
        public int? Age { get; set; }

        public void Validation()
        {
            var errors = DataAnnotationsValidationRunner.GetErrors(this).ToList();

            if (errors.Any())
                throw new RulesException(errors);
        }
    }
}

 

View : Home/Index.aspx に入力フォーム用のタグを追加します。

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2><%= Html.Encode(ViewData["Message"]) %></h2>
    <p>
        To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
    </p>
<div>
    <% using (Html.BeginForm()) { %>
    
    <p><label for="person.Name">名前</label></p>
    <p><% =Html.TextBox("person.Name")%> </p>
    <br />
    <p><label for="person.Age">年齢</label></p>
    <p><% =Html.TextBox("person.Age")%> </p>

    <input type="submit" value="送信" />
    
    <% } %>        
</div>
</asp:Content>

 

Controller : HomeController.cs を修正します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using xValTest.Models;
using xVal.ServerSide;

namespace xValTest.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewData["Message"] = "Welcome to ASP.NET MVC!";

            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Index(Person person)
        {
            ViewData["Message"] = "Welcome to ASP.NET MVC!";

            try
            {
                person.Validation();
                return RedirectToAction("About");
            }
            catch (RulesException ex)
            {
                ex.AddModelStateErrors(ModelState, "person");
                return View();
            }
        }

        public ActionResult About()
        {
            return View();
        }
    }
}

 

4.Helpersフォルダを作成し、DataAnnotationsValidationRunner クラスを作成します。※コードは demo project と同じです。

DataAnnotationsValidationRunner.cs

using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using xVal.ServerSide;

namespace xValTest.Helpers
{
    public static class DataAnnotationsValidationRunner
    {
        public static IEnumerable GetErrors(object instance)
        {
            var metadataAttrib = instance.GetType().GetCustomAttributes(typeof(MetadataTypeAttribute), true).OfType().FirstOrDefault();
            var buddyClassOrModelClass = metadataAttrib != null ? metadataAttrib.MetadataClassType : instance.GetType();
            var buddyClassProperties = TypeDescriptor.GetProperties(buddyClassOrModelClass).Cast();
            var modelClassProperties = TypeDescriptor.GetProperties(instance.GetType()).Cast();

            return from buddyProp in buddyClassProperties
                   join modelProp in modelClassProperties on buddyProp.Name equals modelProp.Name
                   from attribute in buddyProp.Attributes.OfType()
                   where !attribute.IsValid(modelProp.GetValue(instance))
                   select new ErrorInfo(buddyProp.Name, attribute.FormatErrorMessage(string.Empty), instance);
        }
    }
}

 

ここまででサーバーサイドの実装は完了です。続いてクライアントサイドのバリデーションを実装します。 まずは、クライアントサイドの処理で使用するJavaScriptのライブラリを読み込むため、MVC View Master ページのheadに追加します。

Views/Shared/Site.Master

<head runat="server">
    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
    <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
    
    <script type="text/javascript" src="<%= ResolveUrl("~/Scripts/jquery-1.3.2.js")%>"></script>
    <script type="text/javascript" src="<%= ResolveUrl("~/Scripts/jquery.validate.js")%>"></script>
    <script type="text/javascript" src="<%= ResolveUrl("~/Scripts/xVal.jquery.validate.js")%>"></script>    
</head>

 

先ほどフォームを追加した Index.aspx に今度はクライアントサイドでバリデーションを行うため、ネームスペースの追加、エラーメッセージを表示するコード、JavaScript出力コードを追加し、下記のように修正します。

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="xVal.Html"%>
<%@ Import Namespace="xValTest.Models"%>
<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2><%= Html.Encode(ViewData["Message"]) %></h2>
    <p>
        To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
    </p>
<div>
    <% using (Html.BeginForm()) { %>
    
    <p><label for="person.Name">名前</label></p>
    <p><% =Html.TextBox("person.Name")%> </p>
    <br />
    <p><label for="person.Age">年齢</label></p>
    <p><% =Html.TextBox("person.Age")%> </p>

    <input type="submit" value="送信" />
    
    <% } %>        
</div>

<div id="validationSummary">
    <%= Html.ValidationSummary() %>
</div>
    
<%= Html.ClientSideValidation("person", typeof(Person)) 
    .UseValidationSummary("validationSummary") %>    
</asp:Content>

 

これだけで完成です。キャプチャーでは動きがわからないですが、こんな感じになります。同じ定義を書かなくて良いので楽になりますね。

0001

環境:Visual Studio 2008, .NET Framework 3.5

 

Bing API では Webサイト検索 を少し変更するだけで、画像や動画の検索も出来ます。

画像を検索するときは、SearchRequest の Sources プロパティで SourceType.Image を指定し、Search メゾットを実行すると、SearchResponse の Image プロパティに検索結果が入ってきます。

 

aspx
<asp:DataList ID="results" runat="server">
<ItemTemplate>
	<p><asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# DataBinder.Eval(Container.DataItem, "Url")%>' ><img src='<%# DataBinder.Eval(Container.DataItem, "Thumbnail.Url")%>' alt="" /></asp:HyperLink></p>
	<p><%# DataBinder.Eval(Container.DataItem, "Title")%></p>
	<p><%# DataBinder.Eval(Container.DataItem, "Width")%> x <%# DataBinder.Eval(Container.DataItem, "Height")%></p>
</ItemTemplate>
</asp:DataList>
cs
protected void search_Click(object sender, EventArgs e)
{
    using (LiveSearchService liveSearch = new LiveSearchService())
    {
        SearchRequest request = new SearchRequest();
        request.AppId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        request.Query = reqQuery.Text;
        request.Sources = new SourceType[] { SourceType.Image };

        SearchResponse response = liveSearch.Search(request);

        if (response.Image != null)
        {
            count.Text = string.Format("{0} 件中 {1} - {2} 件",
                string.Format("{0:N0}", response.Image.Total),
                response.Image.Offset + 1,
                response.Image.Offset + response.Image.Results.Length);

            results.DataSource = response.Image.Results;
            results.DataBind();

        }
    }
}

 

動画検索を行う場合は SearchRequest の Sources プロパティで response.Video を指定すると、response.Video に検索結果が入ってきます。ソースは、画像検索とほとんど同じです。

aspx
<asp:DataList ID="results" runat="server">
<ItemTemplate>
	<p><asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# DataBinder.Eval(Container.DataItem, "PlayUrl")%>'><img src='<%# DataBinder.Eval(Container.DataItem, "StaticThumbnail.Url")%>' alt="" /></asp:HyperLink></p>
	<p><%# DataBinder.Eval(Container.DataItem, "Title")%> - <%# DataBinder.Eval(Container.DataItem, "SourceTitle")%></p>
</ItemTemplate>
</asp:DataList>
cs
protected void search_Click(object sender, EventArgs e)
{
    using (LiveSearchService liveSearch = new LiveSearchService())
    {
        SearchRequest request = new SearchRequest();
        request.AppId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        request.Query = reqQuery.Text;
        request.Sources = new SourceType[] { SourceType.Video };

        SearchResponse response = liveSearch.Search(request);

        if (response.Video != null)
        {
            count.Text = string.Format("{0} 件中 {1} - {2} 件",
                string.Format("{0:N0}",  response.Video.Total),
                response.Video.Offset + 1,
                response.Video.Offset + response.Video.Results.Length);

            results.DataSource = response.Video.Results;
            results.DataBind();
        }
    }
}

 

SearchRequest や SearchResponse についての詳細は、API documentationをご覧ください。

MSDN Bing API, Version 2
http://msdn.microsoft.com/en-us/library/dd251056.aspx

環境:Visual Studio 2008, .NET Framework 3.5

 

Bing API の Webサイト 検索を SOAP から使ってみます。

Bing API を使用するためには AppID が必要となりますので、Bing Developer Center で取得します。

Bing API を使う(準備)
http://www.gine.jp/blog/taka/post/Bing-API-e38292e4bdbfe38186efbc88e6ba96e58299efbc89.aspx

 

Web 参照の追加 で Bing API Web サービスを追加します。

1.「Web 参照の追加」でURLに「http://api.search.live.net/search.wsdl」を入力し、移動をクリックします。

2.しばらくするとURLの下に「"LiveSearchService"の説明」が表示されますので、メゾット(Search)が表示されたのを確認し、右側の真ん中くらいにある 「参照の追加」 をクリックします。

1001

 

追加が終われば、普通のオブジェクトと同様に使用することが可能となります。下記は Bing API を使って Web サイト検索を行う asp.net の簡単なサンプルです。
※AppId部分は取得した AppID に変更が必要です。

 

default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="default.aspx.cs" Inherits="bing_default" %>

<!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>Bing API で検索</title>
    <style type="text/css">
        p { margin:0 0 0.2em 0;padding:0;line-height:1.2em; }
        .title { font-weight:bold; }
        .description { font-size:smaller; }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <p><asp:TextBox ID="reqQuery" runat="server"></asp:TextBox><asp:Button ID="search" 
                runat="server" Text="検索" onclick="search_Click" /></p>
        <p><asp:Label ID="count" runat="server" Text=""></asp:Label></p>
        <br />
        <asp:DataList ID="results" runat="server">
        <ItemTemplate>
            <p class="title"><asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# DataBinder.Eval(Container.DataItem, "Url")%>' ><%# DataBinder.Eval(Container.DataItem, "Title")%></asp:HyperLink></p>
            <p class="description"><%# DataBinder.Eval(Container.DataItem, "Description")%></p>
            <br />
        </ItemTemplate>
        </asp:DataList>
    </div>
    </form>
</body>
</html>

 

default.aspx.cs

using System;
using net.live.search.api;

public partial class bing_default : System.Web.UI.Page
{

    protected void Page_Load(object sender, EventArgs e)
    {
       
    }

    protected void search_Click(object sender, EventArgs e)
    {

        using (LiveSearchService liveSearch = new LiveSearchService())
        {
            SearchRequest request = new SearchRequest();
            request.AppId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
            request.Query = reqQuery.Text;
            request.Sources = new SourceType[] { SourceType.Web };

            SearchResponse response = liveSearch.Search(request);

            if (response.Web != null)
            {
                count.Text = string.Format("{0} 件中 {1} - {2} 件",
                    string.Format("{0:N0}", response.Web.Total),
                    response.Web.Offset + 1,
                    response.Web.Offset + response.Web.Results.Length);

                results.DataSource = response.Web.Results;
                results.DataBind();
            }

        }
    }
}

 

結果

1002

Bing API を使う(準備)

September 19, 2009

Bing APIを使う前のメモです。

 

AppID の取得

Bing API を使用するためには、App ID が必要となっています。

Bing Developer Center で 「Create an AppID」クリック、必要事項を入力して AppID を取得します。

※Windows Live ID を使用して、「Sign in」する必要があります

Bing Developer Center
http://www.bing.com/developers/

 

Bing API SDK

Bing APIを利用するためのドキュメントとサンプルソースです。C#やVB.NET, JavaScriptで書かれたサンプルソースが入っています。

Bing Developer Center で「Download the SDK」をクリックすると「Bing API SDK」のダウンロードページに移動します。

Bing API SDK
http://www.microsoft.com/downloads/details.aspx?FamilyId=0F513086-078B-47A8-A889-842DC93A69AB&displaylang=en

Server Core(Windows Server 2008 R2) に、PowerShellのServerManagerやWebAdministration用コマンドレットを使用して、IISのインストールと設定、PHPをインストールします。

pkgmgr と AppCmd を使って IIS のインストールや設定する場合は、下記サイトが参考になるかと思います。
http://www.microsoft.com/japan/opensource/php/learning/article3.mspx

 

■PHPのインストール

1.クライアントなどで下記のサイトからWindows Binaries のzip packageをダウンロードします。
http://www.php.net/downloads.php
※今回はPHP 5.2.10 zip package をダウンロードしています。

 

2.ダウンロードしたファイルを解凍し、 Server Core の「c:\php5」にコピーします。
※今回は「c:\php5」にインストールします。

 

3.「php.ini-dist」 をコピーして 「php.ini」 を作成します。

 

4.「php.ini」を notepad などで開いて extension_dir の値を "c:\php5\ext" に変更します。

 

■IISのインストールと設定

1.PowerShell をインストールします。

ServerCore で PowerShell を使う
http://www.gine.jp/blog/taka/post/ServerCore-e381a6-PowerShell-e38292e4bdbfe794a8.aspx

 

2.ServerManager モジュールをインポートします。

サーバー マネージャー用 コマンドレットを使う
http://www.gine.jp/blog/taka/post/e382b5e383bce3838fe383bc-e3839ee3838de383bce382b7e383a3e383bce794a8-e382b3e3839ee383b3e38388e383ace38383e38388e38292e4bdbfe38186.aspx

 

3.IISをインストールします。今回はフルインストールを行っています。

Add-WindowsFeature Web-Server -i

 

4.実行ポリシーが規定だと「Restricted」になっており、スクリプトが実行できないので、スクリプトを実行できるように設定します。

Set-ExecutionPolicy RemoteSigned

 

5.IIS WebAdministration モジュールをインポートします。

import-module WebAdministration

 

6.fastCGIの設定を行います。

Add-WebConfiguration /system.webServer/fastCGI -value @{fullPath="c:\php5\php-cgi.exe"}

 

7.モジュールマップを追加します。

Add-WebConfiguration
 /system.webServer/handlers 
 "IIS:\sites\Default Web Site" 
 -value @{path="*.php";verb="GET,HEAD,POST,DEBUG";name="php";
 modules="FastCgiModule";scriptProcessor="c:\php5\php-cgi.exe"}
※実際のコマンドでは改行は不要です。

 

8.規定のドキュメントに「index.php」を追加しておきます。

Add-WebConfiguration 
 /system.webServer/defaultDocument/files 
 "IIS:\sites\Default Web Site" 
 -value @{value="index.php"}

※実際のコマンドでは改行は不要です。

 

■動作確認

PHPの動作確認のため、「C:\Inetpub\wwwroot」に、以下の内容でtest.phpを作成します。

<?php phpinfo()?>

 

尚、Server CoreにIEはインストールできませんが、Firefoxはインストールできますので、ローカルで確認も可能です。

0001s