WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

IP アドレスで SQL Server に接続

by WebSurfer 2016年3月18日 15:42

サーバー名の代わりに IP アドレスを使って SQL Server に接続に行くと、TCP/IP プロトコルを使って接続に行くようです。

SQL Server への接続

自分の開発マシンには SQL Server 2005 Developer Edition と SQL Server 2008 Express Edition がインストールしてあって、プロトコルは前者が共有メモリのみ有効、後者が共有メモリ、名前つきパイプ、TCP/IP(ポートは 1433)が有効になっています。

そこに、コマンドラインから sqlcmd を使って接続に行くと、(local) の場合は SQL Server 2005 に、IP アドレスの場合は SQL Server 2008 に接続されます。(SELECT @@version; クエリで確認しました)

そして、上の画像で示したとおり、(local) の場合はプロトコルは共有メモリで、IP アドレス(192.168.1.4)の場合は TCP/IP で接続に行きます。

TCP/IP プロトコルを有効にしてあるのは SQL Server 2008 Express のみなので、TCP/IP プロトコルで接続に行く場合、自動的に SQL Server 2008 Express に接続されるということのようです。

知ってました? 実は自分は知らなくて、(local) とかサーバー名を使った場合と同様に SQL Server 2005 Developer Edition に接続に行くと思っていて、半日ぐらいハマってしまいました。(汗)

その他いろいろ新発見があったので、覚えておいたほうがよさそうなことを備忘録として以下に書いておきます。

サーバー名でなく IP アドレスを使った場合、プロトコルを強制的に指定しようとしても、指定できるプロトコルは tcp のみで、np, lpc ではエラーとなって接続できません。実際に試してみたところ、以下の結果となりました。

  • sqlcmd -S tcp:192.168.1.4 -E ⇒ OK
  • sqlcmd -S np:192.168.1.4 -E ⇒ NG
    エラーメッセージ:Named Pipes Provider: Could not open a connection to SQL Server [64].
  • sqlcmd -S lpc:192.168.1.4 -E ⇒ NG
    エラーメッセージ:SQL Server Network Interfaces: Cannot open a Shared Memory connection to a remote SQL Server instance [87].

sqlcmd -S (local) -E または sqlcmd -S <サーバー名> -E は SQL Server 2005 に共有メモリを使って接続されます。

sqlcmd -S (local)\sqlexpress -E または sqlcmd -S <サーバー名>\sqlexpress -E は SQL Server 2008 Express に共有メモリを使って接続されます。

インスタンス名を追加して sqlcmd -S 192.168.1.4\SQLEXPERESS -E とすると "SQL Server Network Interfaces: Error Locating Server/Instance Specified [xFFFFFFFF]." というエラーとなって接続に失敗します。sqlcmd -S 192.168.1.4\SQLEXPERESS,1433 -E というようにポートを指定すれば接続できます。

その理由は、先の記事 SQLEXPRESS は「名前つきインスタンス」名で書きましたように、インスタンス名を指定した場合、UDP 1434 (SQL Browser サービス) に接続して、指定したインスタンス名のポート番号を取得し、その後対象ポートに接続をするという動作になるからのようです。

MSDN Blog の記事 Troubleshooting Connectivity #1 – SQL Server への接続によると、SQL Server に接続する場合、以下の 3 つのステップにで処理が行われるそうです。この記事の話は「OS レベルのセッション確立」のステップに該当します。

  1. OS レベルのセッション確立
  2. ログイン認証
  3. データベースアクセス

上に紹介した MSDN Blog の記事にはいろいろ参考になることが書いてありますので、一読されることをお勧めします。あと、Troubleshooting Connectivity #5 – セッション確立までの動作という記事も参考になると思います。

Tags: ,

SQL Server

DataType 属性による検証

by WebSurfer 2016年3月8日 17:21

データアノテーション検証でのデフォルトのエラーメッセージと DataType 属性による検証についておぼえておいた方がよさそうなことを備忘録として書きます。

エラーメッセージ

上の画像は、下のサンプルコードの Model のパブリックプロパティに付与したデータアノテーション属性によるエラーメッセージです。

(注1:上に表示されているエラーメッセージは全てクライアント側での検証結果によるものです。)

(注2:BrithDate (html で input type="date" となる) はブラウザ依存の動きとなります。IE9, IE11 では自由な文字列の入力ができ、0001 で何故かクライアント側での検証はパスします。ただし、サーバー側で検証がかかって、コントローラーで ModelState.IsValid は false になります。エラーメッセージは上記と違って「値 '0001' は BirthDate に対して無効です」となります)

なお、自分が検証に使った環境は Vista SP2 32-bit, .NET 4, Visual Studio 2010 プロフェッショナル, MVC4 のインターネットアプリケーションのテンプレート使用、ASP.NET 開発サーバー利用、IE9, IE11 です。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace Mvc4App2.Models
{
  public class DefaultErrorMessage
  {
    [Required]
    public string Name { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [RegularExpression(@"^(?=.*\d)(?=.*[A-Z])[A-Z0-9]{4,8}$")]
    public string PassWord { get; set; }

    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }

    [DataType(DataType.PhoneNumber)]
    public string Phone { get; set; }

    [DataType(DataType.Date)]
    public DateTime BirthDate { get; set; }

    [DataType(DataType.Url)]
    public string Url { get; set; }

    [StringLength(10)]
    [DataType(DataType.MultilineText)]
    public string Message { get; set; }
  }
}

各属性の ErrorMessage プロパティに何も設定しなくても上の画像のようにデフォルトでエラーメッセージが出ます。

しかし、正規表現がそのまま出たり(「フィールド PassWord は正規表現 '^(?=.*\d)(?=.*[A-Z])[A-Z0-9]{4,8}$' と一致する必要があります。」とか言われても一般ユーザーには訳がわからない)、一部はローカル化されておらず英文のままだったりとユーザーフレンドリーとは言えないようです。

さらに、MSDN フォーラムのスレッドASP.NET MVC5 でVaridateメッセージが英語で初めて知りましたが、自動的に��ローカル化されず全部英語になってしまうこともあるようです。

また、DataType 属性については、付与しても検証は行われずエラーメッセージは出ないものがありますので注意が必要です。上の例では Password, PhoneNumber, MultilineText では検証が行われていません。

Password と MultilineText にはエラーメッセージが出ていますが、それは DataType 属性によるものではなく、追加で付与した RegularExpression 属性と StringLength 属性によるものです。

一方、EmailAddress, Date, Url は検証がかかります。クライアント側での検証はブラウザ依存になると思いますので自分が試した IE9 以外で同じ結果になるかは分かりませんが(未検証・未確認です)。なので、DataType 属性による検証に頼らず、自分で StringLength 属性や RegularExpression 属性等を使ってきちんと検証したほうがよさそうです。

ただし、DataType 属性を付与することによるメリットは検証以外にもあります。それは、View のコードに全て Html.EditorFor を利用しても、DataType 属性によって生成される html ソースの input 要素の type 属性が変わってくる(MultilineText の場合は input 要素でなく、textarea 要素になる)ことです。ちなみに、上の Model の DataType 属性の設定では以下のようになります。

<input ... name="Name" type="text" value="" />
            
<input ... name="PassWord" type="password" value="" />
            
<input ... name="Email" type="email" value="" />
            
<input ... name="Phone" type="tel" value="" />
            
<input ... name="BirthDate" type="date" value="0001/01/01" />
            
<input ... name="Url" type="url" value="" />

<textarea ... id="Message" name="Message"></textarea>

それゆえ、Password と MultilineText にいては DataType 属性を付与するのがよさそうです。他のデータアノテーション属性による検証とバッティングすることもなさそうですし。

以上のような訳で、DataType 属性による検証やデフォルトのエラーメッセージでは期待した結果を得るのは難しいので、

  1. DataType 属性による検証は利用せず Range, RegularExpression, Required, StringLength 属性などを組み合わせて使う。
  2. DataType 属性を使用するのは、Password や MultilineText のように、レンダリングされる html ソースの input 要素の type 属性を "password" にしたいとか、input 要素でなく textarea 要素にしたい場合に限る。
  3. エラーメッセージは自分で各データアノテーション属性の ErrorMessage プロパティに設定する。(先の記事「コレクションのデータアノテーション検証」参照)
  4. Model のコード内にエラーメッセージをハードコーディングしたくない場合は自分でリソースファイル (.resx) を作って使う。(先の記事「データアノテーション検証の多言語対応」参照)
  5. エラーメッセージを多言語化する場合は自分でリソースファイルを追加してサテライトアセンブリを作って使う。(同じく、先の記事「データアノテーション検証の多言語対応」参照)

というようにするのが正解だと思いました。

-------- 2016/6/17 追記 --------

ErrorMessage プロパティの設定は行わず、デフォルトの日本語のエラーメッセージを利用したいのであれば、Azure など特にサーバーが外国にある場合は Culture, UICulture を "auto" に設定するのを忘れないようにしてください。

Culture, UICulture を "auto" に設定すると、ASP.NET は、ブラウザから送信されてくる要求ヘッダに含まれる Accept-Language の設定を調べて、その要求を処理するスレッドのカルチャを Accept-Language に設定されているカルチャに書き換えます。

そして、リソースマネージャが実行時に、Thread.CurrentUICulture などで 得られる CultureInfo(現在の要求を処理しているスレッドのカルチャ情報)を参照してローカライズされたリソースを検索し、UI に表示されるテキストを取得するという仕組みになっています。

Culture, UICulture を "auto" に設定するのを忘れるとブラウザの言語設定は無視されます。デフォルトではシステムのロケールに該当するカルチャがスレッドに設定されますので、例えば英語 OS では英語のリソースから UI に表示されるテキストを取得します。(日本語のリソースがあっても使われません)

Tags: ,

Validation

Chart Samples

by WebSurfer 2016年2月14日 16:15

注意: 下に書いたサンプルの入手先 Samples Environments for Microsoft Chart Controls は 2021/11/30 現在リンク切れです。Windows Forms アプリ用だけは別の入手先を見つけましたので、それを「Windows Forms 用 Chart Samples」に書いておきます。

先の記事 Chart で ASP.NET Web Forms アプリでグラフを表示するのに便利な Chart コントロールを紹介しましたが、MSDN のサイトからサンプルを入手できるので、入手方法その他備忘録として残しておいたほうがよさそうなことを書いておきます。

Chart Samples

まず入手先ですが、以下のページから Windows Forms アプリ用と ASP.NET Web Forms アプリ用のサンプルをダウンロードできます。

Samples Environments for Microsoft Chart Controls

Windows Forms 用のサンプルは上のページで[C# (5.6MB)]をクリック、ASP.NET Web Forms アプリ用なら[HTML (4.4MB)]の方をクリックしてください。両方入手したいなら[Full (10.0MB)]をクリックしてください。

「Samples Environments for Microsoft Chart Controls.zip」という名前の zip ファイルの中に、Windows Forms 用なら「Windows Forms Samples Environment for Microsoft Chart Controls\C#」というフォルダがあって、それに完全な Windows Forms アプリのソリューションとしてサンプルが含まれています。

ASP.NET Web Forms アプリ用なら「ASP.NET Samples Environment for Microsoft Chart Controls\HTML」というフォルダがあって、それに完全な ASP.NET Web Forms アプリの Web サイトプロジェクトとしてサンプルが含まれています。

それを適当なフォルダに解凍して Visual Studio(.NET4 なので 2010 以降のバージョン)で開いて実行すれば、基本の解説、いろいろなタイプのサンプルのデモ、それを作るための C# および VB.NET サンプルコード等が満載のアプリが動くはずです。

上の画像は Windows Forms アプリ用のサンプルを実行したときのものです。ASP.NET Web Forms アプリ用は同様なサンプルがブラウザ上に表示されます。

解説が英語であるのを厭わなければこのサンプルは非常に有益なものになると思います。というか、このサンプル無しでは Chart を使っての開発は難しいと言っても過言ではないと思います。

一つだけ注意事項があります。Windows Forms アプリのサンプルは、ソリューションのフォルダ名が zip を解凍したときのままですと以下の画像のように C# と言う名前になっており、これをそのままソリューションのフォルダとして使う場合は、フォルダ名 C# を CSharp などに書き換えないとうまく動かないということです。(最後が # で終わるのは不可)

フォルダ構成

ちょっと余計な話ですが、何故 '#' があるとダメなのかも調べたので、以下にその理由も書いておきます。

プログラムの中で Application.ExecutablePath プロパティを利用してパス名を得ていますが、.exe ファイルの出力パスが .\ と設定されているので、フォルダ名が C# のままですと得られるパス名の文字列は "C:\ ... \\Windows Forms Samples Environment for Microsoft Chart Controls\\C#/WinFormsChartSamples.exe" となってしまいます。(C# の直後が '\\' ではなくて '/' であることに注意)

その後、上記文字列からファイル名を除去するのに applicationPath.LastIndexOf('\\'); でインデックスを取得しているのですが、'\\' を期待しているところが '/' になっているのでうまく行きません。

C# を CSharp などに書き換えると "C:\ ... \\Windows Forms Samples Environment for Microsoft Chart Controls\\CSharp\\WinFormsChartSamples.exe" となって期待通りに行きます。

何故 C# の直後が '\\' ではなくて '/' なってしまうかと言うと Application.ExecutablePath のコードで '#' が fragment と見なされるからだそうです。

その詳細は stackoverflow の記事 Odd C# path issue にありますので興味があれば見てください。(手抜きですみません)

Tags:

.NET Framework

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。

Calendar

<<  2024年4月  >>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar