2018年6月4日月曜日

ASP.NET Identity Facebook認証失敗

VS2015+Owin3.0.1を使用してFacebookで単純な認証処理を実装しようとして無駄にはまってしまったので忘れないようにメモ

環境

  • Visual Studio 2015
  • .Net Framework 4.6.1
  • ASP.NET MVC 5
  • Microsoft.Owin 3.0.1.0

現象

  1. Facebook developer設定。
  2. ASP.NET 新規MVCサイト作成。
  3. Startup.Auth.csのFacebook認証箇所コメントアウトを外す。(app.UseFacebookAuthentication)
  4. appId,appSecretを設定(手順1の操作で取得したもの)
  5. 起動してログイン画面、"Facebook"を選択


認証は通っているように見えるが、下記問題が発生

  • AccountController ExternalLoginCallbackメソッド内のAuthenticationManager.GetExternalLoginInfoAsync戻り値がNullになる。
  • Facebookから戻ってきた後ログイン画面がまた表示される。またURLが”http://localhost:xxxxx/Account/Login?_=_”となる。(後ろに_=_が追加された状態)


対応方法

NugetでMicrosoft.Owin関係のバージョンを3.1以上に、Newtonsoft.Jsonのバージョンを10.0以上にあげる。

※Visual Studio 2015で作るとMicrosoft.Owinが3.0.1




2018年5月30日水曜日

ASP.NET Identity Twitter認証で「応答の状態コードは成功を示していません」エラー

訂正


2018/08/01 時点 Twitter Application Managementの設定が変更(APIの仕様変更)になったため、 2018/5/30に書いた当ページの方法では動作しなくなりました。


※Enable Callback Lockingの設定がなくなりました。

対処方法

 Twitter Application Managementの設定 「Callback URLs」に「http://localhost:xxxxx/signin-twitter」を設定。
※xxxxxは動作環境のポート番号

もともとの設定でCallback URLsに設定してた値のミスが原因でした。
Enable Callback Lockingの設定関係なく、正しくCallback URLs指定してれば発生しない問題です。orz



概要

ASP.Net Identityの基本認証を使用しTwitterアカウントでの認証を実装しようとしたところ、「応答の状態コードは成功を示していません: 403 (Forbidden)。」が発生し、軽くはまってしまったので、対象方法メモ。




前提条件

環境

  • Visual Studio 2015
  • .Net Framework 4.6.1 
  • ASP.NET MVC 5

状況

  1. 新規にWEBプロジェクトを作成(ASP.NET MVC指定。認証は個別のユーザーを指定)
  2. Twitter Application Management の設定を行う。
  3. ASP.Net Identity でTwitterの認証を有効にする。※
  4. WEBサイト起動し、ログイン→Twitterをクリックする。
  5. エラーが発生

※手順1~3の詳細は割愛。
※「検証プロシージャによると、リモート証明書は無効です」エラーが発生する場合は下記サイトの対応を実施
https://stackoverflow.com/questions/25011890/owin-twitter-login-the-remote-certificate-is-invalid-according-to-the-validati

対応方法


Twitter Application Management の設定で
Settings -> [Enable Callback Locking]のチェックを外す。


  • ※2018/05/30 デフォルトはチェックありでした。

その他

チェック外していいのか、って所がよくわかってません。
どんなパターンで問題になるんだろ。。


2017年4月25日火曜日

sphinx-autobuildをWindowsで使ってみる

Sphinxでドキュメント作る際に、ビルドの手間を軽減してくれる「sphinx-autobuild」を windowsで使用する際にはまったのでメモ

前提条件

Sphinxがインストールされていること。


環境

  • Windows 7
  • Python 2.7
  • Sphinx 1.3.1
  • sphinx-autobuild 0.6.0 ←今回環境を作るやつ
※Sphinxとはといったことについては割愛


インストール

pip install sphinx-autobuild

使い方

sphinx-autobuild <ソースディレクトリ> <ビルド成果物出力ディレクトリ>

※コマンド実行後http://127.0.0.1:8000アクセス


インストールと使い方は下記サイト参考にしました。
http://qiita.com/mikanbako/items/28a3fc5d1da42939f941


Sphinxプロジェクトのファイル名・パスに全角がある場合


ファイル名やパスに全角があると「UnicodeDecodeError」が発生し、ブラウザで表示しても500エラーが表示される。
原因はPython2.xの場合文字コードの初期値がasciiコードだが、WindowsのファイルパスはShift-JISのため。
この場合、sitecustomize.pyというテキストファイルを作成し、下記の2行を記載、Pythonインストールフォルダ内にある「site-packages」フォルダを探し、直下に保存する。(ファイル自体の文字コードはShift-JISで作成する。)

import sys
sys.setdefaultencoding('cp932')


※Sphinxのドキュメント自体はUTF-8で記述しなければいけないのが地味に問題をややこしくします。


2015年9月4日金曜日

DapperExtensionsを使ってみる2

前回に引き続きDapperExtensionsの小ネタです。
※我ながら遅筆にもほどがある。


今回は、テーブル名や、カラム名がエンティティクラスと異なる場合や、
主キーが複数の場合の対応です。特に主キーは1個にしといてよっと
いいたいところなんですが、会社で業務アプリをさわってる以上、
避けられない、っというか、ほぼ全部ですよってことで。


やり方

前回は複数形のテーブル名を単数形のクラス名に変換するためにすでに準備されている、PluralizedAutoClassMapperをDapperExtensions.DefaultMapperに 設定しましたが、今回はこの部分をカスタムで作ってやる必要があります。


前提条件


こんなテーブルがあったとします。(テーブル名は"syain")


こんなエンティティクラスにMappingしたいです。
public class Person
{
    public int BuilderId { get; set; }
    public string PersonId { get; set; }
    public string Name { get; set; }
}

  • gyousya_id(int)とsyain_id(nvarchar)で複合キー
  • テーブル名syainをPersonに
  • カラム名gyosya_idをBuilderIdに
  • カラム名syain_idをPersonIdに
  • カラム名namaeをNameに


とりあえずやってみる


1.CustomMapperの作成


DapperExtensions.Mapper名前空間にあるClassMapperを継承したCustomMapperを作成します。
01:using DapperExtensions.Mapper;
02:public sealed class CustomClassMapper< T > : ClassMapper< T > where T : class
03:{
04:    public CustomClassMapper()
05:    {
06:        if (typeof(T) == typeof(Person))
07:         {
08:             Table("syain");
09:             Map(x => (x as Person).BuilderId).Column("gyosya_id").Key(KeyType.Assigned);
10:             Map(x => (x as Person).PersonId).Column("syain_id").Key(KeyType.Assigned);
11:             Map(x => (x as Person).Name).Column("namae");
12:        }
13:         AutoMap();
14:    }
15:}

2.DefaultMapperの指定


先ほど作成したCustomMapperをDefaultMapperに指定します。
DapperExtensions.DapperExtensions.DefaultMapper = typeof(CustomClassMapper<>);
この処理はアプリケーション起動時に1回呼ぶだけでおっけーです(前回と一緒です)。 あとはInsert/Update/Deleteも前回と同じ方法で行うことが可能です。


解説・ポイント


  • 01行目:DapperExtensions.Mapper空間のClassMapperを継承したクラスを作成します。
  • 04行目:コンストラクタを作成します。この中にマッピング定義を記載します。
  • 06行目:マッピング対象のクラスを判別します。複数テーブルのマッピングを定義する場合は、ここで切り分けます。
  • 08行目:テーブル名のマッピング定義です。エンティティクラス名とテーブル名が同一の場合は不要です。
  • 09~10行目:主キーが複数の場合の定義です。
  • 11行目:カラム名のマッピング定義です。テーブル名同様、変更がない場合は不要です。
  • 13行目:これはデフォルトのマッピングを追加するメソッドになります。テーブルに「birthday」というカラムがあり、エンティティクラスにも「birthday」という同名のプロパティがある場合必要になります。(今回の例の場合不要ですが、やらないと全定義を記載する必要があるため参考までに記載してあります。)

ポイントとなるのは9~10行目です。今回はカラム名のマッピングとキー指定を同時に行っているため、Column("~").Key(KeyType.Assigned)といった記載になります。
カラム名のマッピングが不要の場合はColumn("~")の部分は不要です。


感想

テーブル数の数だけ、Mapping定義を追加していかなくてはならないので、最初がとても
めんどうです。が、1回設定してしまえば終わりなので(データベースの主キーや名前が変わる
ってことはまずないので)、そこさえ乗り切ってしまえば、さくさく使えるようになって便利です!


2015年5月19日火曜日

DapperExtensionsを使ってみる

Dapperの拡張ライブラリDapperExtensionsについてです。


Dapperとは

 
  すでに解説されてる方がたくさんいらっしゃるので、そちらをご覧ください。


DapperExtensionsとは

  
DapperはORMと冠しているものの、実際はクエリすべて手打ちです。(それがいいんですが)
なんですが、単純なSELECTやINSERT、UPDATE、DELETEはいちいち手打ちするのも面倒!
そんな時に、さくっとかけるようになるDapperの拡張ライブラリです。
 

DapperExtensionsの基本的な使い方


※以下コード部分はC#で記載します。

まず、DapperとDapperExtensionsをNugetなどでプロジェクトに追加します。

PM> Install-Package Dapper
PM> Install-Package DapperExtensions


例えばこんな構成のPersonsテーブルがあったとして、
※主キーはIdentity








こんな、エンティティクラスがあったとします。
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}


登録処理を記述するクラスにDapperと、DapperExtensions名前空間をusing します。
 using DapperExtensions;
 using DapperExtensions.Mapper;


今回はテーブル名がPersons、エンティティクラス名がPerson、なので複数形と単数形を変換するルールをプログラム開始時に指定します。
(この処理は1回だけ呼べばOKです。)
DapperExtensions.DapperExtensions.DefaultMapper = typeof(PluralizedAutoClassMapper<>);

Connectionオブジェクトを作成します。

 var connection = new SqlConnection("<接続文字列>");
 connection.Open();

あとは以下ような感じで登録・更新・削除できます。

新規登録(Insert)

connection.Insert(new Person { Name = "テスト太郎" });

更新(Update)

connection.Update(new Person { Id = 1, Name = "テスト太郎更新" });

削除(Delete)

connection.Delete(new Person { Id = 1 });


※connectionのDispose処理記載するの省略してます。

その他

※デフォルトではテーブルの主キーが1つで、IdやPersonIdといった名称の場合にのみ対応します。
複合キーだったりした場合は別途マッピングルールを指定する必要があります。(あとテーブル名とエンティティクラス名が異なる場合とか)
(最初それについて書くつもりだったんですが、だらだらと長くなりそうだったので次回)

雑記

会社で業務システムに携わってるとあれな設計のテーブルも多く(1テーブルカラム100以上とか)、 そういったテーブルに対していちいち単純なSQL文書くのもめんどくさいのでとても重宝してます。

エンティティクラスと条件指定して簡単な検索(SELECT文発行)なんかもできるんですが、これについてはDapperExtensions使わずに、素直にクエリ書いたほうが楽だと思います。条件の指定方法が独特だったり、少し複雑にしようと思うと対応できなかったりします。

2014年12月16日火曜日

NPOIで改ページを設定する

.Net Framework用エクセル編集ライブラリのNPOIで改ページをする方法です。

NPOIのバージョンは2.0.6.0、動作確認に使用したExcelは2002です。(ふるっ)

会社ではエクセル出力の要望が多く、NPOIは簡単なエクセルなら
すぐできてしまうのでとても便利です。
//エクセルブックとシートのオブジェクト作成
IWorkbook  book = new HSSFWorkbook();
ISheet sheet = book.CreateSheet("testsheet");
//適当なデータを設定
for (int i = 0; i < 6; i++)
{
 var row = sheet.CreateRow(i);
 for (int j = 0; j < 6; j++)
 {
  var cell = row.CreateCell(j);
  cell.SetCellValue(string.Format("({0},{1})", i + 1,j + 1));
 }
}
using (var fs = new FileStream(@"d:\test.xls", FileMode.OpenOrCreate, FileAccess.Write))
 book.Write(fs);

この時に印刷範囲の指定をしようとしてはまりました。
NPOIにはISheetインタフェースにSetRowBreak、SetColumnBreakというメソッドが
あるのでこれを指定するだけ、と思いましたが期待通りの動作はしてくれません。

//エクセルブックとシートのオブジェクト作成
IWorkbook  book = new HSSFWorkbook();
ISheet sheet = book.CreateSheet("testsheet");
//適当なデータを設定
for (int i = 0; i < 6; i++)
{
 var row = sheet.CreateRow(i);
 for (int j = 0; j < 6; j++)
 {
  var cell = row.CreateCell(j);
  cell.SetCellValue(string.Format("({0},{1})", i + 1,j + 1));
 }
}

sheet.SetRowBreak(2); //追加
sheet.SetColumnBreak(2); //追加

using (var fs = new FileStream(@"d:\test.xls", FileMode.OpenOrCreate, FileAccess.Write))
 book.Write(fs);
※エクセルの3列目と3行目に改ページを行う設定を追加



対処方法ですが、SheetオブジェクトのFitToPageプロパティをFalseに設定すれば
思ったとおりの動作をしてくれます。

//エクセルブックとシートのオブジェクト作成
IWorkbook  book = new HSSFWorkbook();
ISheet sheet = book.CreateSheet("testsheet");
//適当なデータを設定
for (int i = 0; i < 6; i++)
{
 var row = sheet.CreateRow(i);
 for (int j = 0; j < 6; j++)
 {
  var cell = row.CreateCell(j);
  cell.SetCellValue(string.Format("({0},{1})", i + 1,j + 1));
 }
}

sheet.SetRowBreak(2);
sheet.SetColumnBreak(2);
sheet.FitToPage = false; //追加
using (var fs = new FileStream(@"d:\test.xls", FileMode.OpenOrCreate, FileAccess.Write))
 book.Write(fs);



FitToPageはシートを1ページに収まるように自動で調整するプロパティでデフォルトでTrueになっているため、SetRowBreak,SetColumnBreakを設定してもこちらが優先されてしまうようです。

2014年7月22日火曜日

SchemaSpyを使ってSQL Serverからテーブル定義書とER図の自動出力(Windows)

記念すべき初投稿です。

ということで、早速ですが、タイトル通りSchemaSpyを使ったテーブル定義書の出力について、いろいろはまったのとWindows+SqlServerの組み合わせでの解説が意外となかったので、個人的にメモをします。

SchemaSpyとは


Javaで作成されている、データベースを解析して、設定したコメントや、外部キー設定などから、テーブル定義、ER図をhtml形式で出力してくれるツール。
コマンドベースなので設定さえしてしまえば後は、自動実行といったことが可能です。

本家サイト
出力サンプル(本家)

必要な作業

  1. Javaのインストール
  2. Graphivizのインストール
  3. SchemaSpy実行ファイルの準備
  4. SQL Server JDBCドライバの準備
  5. コマンドの実行

なお、私の動作環境はWindows Server 2008 R2、SQL Server 2008 R2です。(SQL Server 2005でも動作しました。)


設定手順


1.Javaのインストール


Javaをインストールして、パスを設定します。本家サイトでは"Java 5 or higher"となっています。私の環境では2014年7月17日時点最新のJava Version 7 Update 56をインストールしました。

2.Graphvizのインストール


ER図の出力に必要なGraphvizをインストールします。なくてもSchemaSpy自体は動作するのですが、ER図が出力されないので、魅力半減です。インストールするだけで小難しい設定は不要なので迷わずインストールすることをお勧めします。

以下のサイトからダウンロードしてインストールします。
Graphviz

私の環境ではバージョン2.38をインストールしました。古いバージョンだとうまく出力されない場合があるようです。また、インストール後、Windows環境変数のPathにGraphvizインストールフォルダのbinに対してパスが設定されているか確認します。
(パスが通ってない場合は手動で追加)


3.SchemaSpy実行ファイルの準備


上述、本家サイトの左メニューを選択して最新のschemaSpy_5.0.0.jarをダウンロードするだけです。


っと、いいたい所なんですが、うまく動きません。(一番はまりました)

実行可能ファイルの更新は2010年からとまっており、SQL Server 2008には対応してないようです。
また、SQL Server 2005でも同様で、コメントが出力されなかったり、ER図が出力されなかったりしました。

ただし、ソースファイル自体は更新され続けています。ソースはSubversionで以下で取得できます。

svn checkout svn://svn.code.sf.net/p/schemaspy/code/trunk schemaspy-code

あとはEclipseなんかで開いて実行可能Jarファイル作成すればOKです!
(このために10年ぶりにEclipseさわりました。。)


4.SQL Server JDBCドライバの準備


データベースへ接続するためのJDBCドライバを準備します。これはJarファイルをダウンロードするだけです。

jtds-1.3.1-dist.zip


※SQL Server 2012に接続する場合は別のドライバが必要みたいです(未確認)

5.コマンドの実行


ここまでで準備はできたので、あとは適当なフォルダを作成して、SchemaSpy本体Jarファイルと、JDBCドライバJarファイルを保存し、同ディレクトリにてコマンドプロンプトから実行するだけです。

java -jar schemaspy.jar -s dbo -dp jtds-1.3.0.jar -t mssql05-jtds  -db <dbName> -host "<hostName>" -o "<出力先ディレクトリ>" -u <ユーザー名> -p <パスワード> -charset utf-8 -port 1433 -norows


私は以下のようにバッチファイルを作成して実行しています。
java -jar schemaspy.jar  ^
-s dbo ^
-dp jtds-1.3.0.jar ^
-t mssql05-jtds  ^
-db  ^
-host ""  ^
-o "<出力先ディレクトリ>"  ^
-u <ユーザー名>  ^
-p <パスワード>  ^
-charset utf-8   ^
-port 1433 ^
-norows
細かい内容は本家サイトに書いてありますが、注意点は"-s"の部分です。
本家の説明では特に必要といった記述はありませんでしたが、ないと動作しませんでした。
また"-t"の部分は、データベースの種類を指定する場所ですが、SQL Server 2008でも"mssql05-jtds"でいいようです。



使用してみた感想


会社ではさらにこれをJenkinsに登録しています。作業の流れ的には

  1. Visual Studioのデータベースプロジェクトでスキーマ修正、コミット
  2. Jenkinsでプロジェクトビルド、テストサーバーにデータベースの変更を反映
  3. データベースの変更完了後、SchemaSpy+Jenkinsにて定義書自動出力
といったことをやっています。何もしなくても常に仕様書が最新に保たれてる状態なので、とても気分がよく、どや感が半端ないです。

あとER図がとても見やすいです。(最初は.netで自分で作ろうかとも考えてたんですが、SchemaSpyのER図見た瞬間やめました。)
また、全体だけではなく、それぞれのテーブルを中心としたER図を見れるのも便利です。

VisioやA5:SQL Mk-2等、データベースから定義書・ER図出力をするツールはいくつか試しましたが、テーブルが50,100を超えるスキーマがざらにあるうちの開発では手作業では正直やってらんないです。(変更もしょっちゅうだし....)


今後活躍していくことになりそうです。
(せっかくEclipseもいれたことだし、改造してStoredの一覧なんかも出力できたらいいなぁ)



参考サイト