ASP.NET MVCをIISの仮想フォルダに公開したら404エラーになる件
エラーの原因
ASP.NETのルーティングとJavascriptのURL実行部をIISの仮想フォルダまでは考慮していなかったため、ルーティングが失敗し、存在しないページを探しに行ってエラーになる感じ
エラーになる主な部分
- HTML部のformactionとスクリプトソース設定の方が失敗していました。
<form method="post" enctype="multipart/form-data"> <button itype="submit" formaction="/Home/Action1" >処理</button> </form> <script src="~/Scripts/IMyScript.js"></script>
- javascriptは言うこともないが、パス合わなくなりますね。
var ret = $.ajax({ type: 'GET', url: '/Home/Action1', async: false }).responseText;
対応した部分
- RouteConfigに仮想フォルダ用のルーティングを追加
routes.MapRoute( name:="SUB", url:="SUB/{controller}/{action}/{code}", defaults:=new {controller = "Home", action = "Index", code = UrlParameter.Optional} )
- View部分には@Url.Contentを使用
<form method="post" enctype="multipart/form-data"> <button itype="submit" formaction='@Url.Content("~/Home/Action1")' >処理</button> </form> <script src='@Url.Content("~/Scripts/IMyScript.js")'></script>
*JavascriptにはルートのUrlを再生性するため、_Layoutにルート情報を隠しといて再生成関数を配置
<input id="hdnRootUrl" type="hidden" value='@Url.Content("~/")' />
var myurl = $('#hdnRootUrl').val() + '/Home/Action1'; myurl.replace('//', '/'); var ret = $.ajax({ type: 'GET', url: myurl, async: false }).responseText;
ASP.NET ファイルアップロード関連トラブル
ファイルアップロード時、以下のエラーに遭遇
- maxAllowedContentLength エラー
- 要求の長さの最大値を超えました。 POSTされるファイルの最大サイズが引っかかる場合、発生。 maxRequestLengthが足りない場合起きるエラー 大容量のCSVファイルなどは最大容量で引っかかるらしい、 以下の様に、httpRuntimeに最大設定で回避
<system.web> <httpRuntime maxRequestLength="65535"/> </system.web>
IIS7以降ではサーバの要求フィルター設定項目でも、ファイルサイズの 上限を設定する必要がある。らしい
<system.webServer> <modules runAllManagedModulesForAllRequests="true" /> <security> <requestFiltering> <requestLimits maxAllowedContentLength="120000000"/> </requestFiltering> </security> </system.webServer>
CsvHelperを利用して、Csvデータを取り込む
Nugetより、CsvHelperをインストールする。
Csvを読み取り、モデルに設定してくれるパッケージ まあ、便利そうだから入れる。
Csvファイルサンプル
Code,Name 001,Tokyo 002,Osaka 003,Nagoya 004,Hakata 005,Yokohama
Csv取込用モデル作成
Public class MyData { Public string Code {get; set;} Public string Name {get; set;} }
Csvファイルを読み取る
Public void main() { Dim fs As FileStream = System.IO.File.Open("csv_data\\testcsv.csv", FileMode.Open) using(var sr = new StreamReader(fileStream, System.Text.Encoding.GetEncoding("shift_jis")) { var cr = new CsvHelper.CsvReader(sr); While(csvReader.Read()){ var data = csvReader.GetRecord(Of MyData)() } } }
注意点
CsvHelperでモデルにバインドする場合は、ヘッダーにモデルの項目名と一致しないとエラーになるため、注意が必要
SQLCMDでSELECT結果をCSV出力する。
SELECT文の結果をSQLCMDを利用し、CSV出力する
query.sql
クエリを指定したファイル
SET NOCOUNT ON; SELECT [Code] ,[Name] FROM [dbo].[Data] ;
SET NOCOUNT ON;を削除すると件数が一緒に出力される。
SQLCMD
query.sqlを読み取り、output.csvファイルへ出力する。
SQLCMD -S localhost -U sa -P {password} -d {dbname} -i query.sql -s, -W -h -1 -o output.csv
- オプションについて
命令 | 説明 |
---|---|
-S | サーバ名 |
-U | ログイン |
-P | パスワード |
-d | データベース |
-i | スクリプトファイル |
-s | 区切り文字 |
-W | 余計な空白を省く |
-h | -1でヘッダ非表示 |
-o | 出力ファイル |
-v | 変数 (param='001' => $(param)) |
-h オプションについて
-h -1の場合、ヘッダーが一切出力されなくなる。
001,Tokyo 002,Osaka 003,Nagoya 004,Hakata 005,Yokohama
-hオプションなしの場合
Code,Name ----,---- 001,Tokyo 002,Osaka 003,Nagoya 004,Hakata 005,Yokohama
ASP.NET MVC FILE UPLOAD
ASP.NET MVCでファイルをアップロードする方法を調べる
以外なところでハマり、悩まされたので、メモる。
Controllerでもファイルの受け取り方法
- Modelにバインドして取得する。
- Request.Filesから、inputのnameをキーに取得する。
public ActionResult Upload(FormCollection form) { var file = Request.Files["uploadfile"]; } もしくは public ActionResult Upload(MyViewModel model) { model.UploadFile; // -> すでにバインド状態となる。 }
View側での準備
- formのmethodはPOST
- formのenctypeは"multipart/form-data" ←これがわからず悩んだ
- inputのtype=file, name=取得キーもしくはModelの項目名と一致すること
<form method="post" enctype="multipart/form-data"> <input type="file" name="uploadfile" /> <button type="submit" > UPLOAD</button> </form> もしくは @Using(Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype="multipart/form-data"}) { <input type="file" name="uploadfile" /> <button type="submit" > UPLOAD</button> }
ViewModel定義
基本、対象項目の型を”HttpPostedFileBase”にしておくだけ
Public calss MyViewModel
{
public HttpPostedFileBase UploadFile;
}
ASP.NET MVCでjQueryが動作しない
SCRIPT5009: '$' is not defined
jQueryをすべて正しく設定してもこのエラーになってしまう。
解決
@Scripts.Render("~/bundles/jquery")をヘッダー部に設定する。
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - マイ ASP.NET アプリケーション</title> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") @Scripts.Render("~/bundles/jquery") <!-- 下部にあったjqueryをヘッダー部へ移動した。 --> </head> <body> // 省略 @*Scripts.Render("~/bundles/jquery")*@ @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", required:=False) </body> </html>
Visual StudioのLocalDb管理
LocalDb
Visual Studioから、ローカル用にLocalDbの追加が可能になっている。
※詳細については
SQL Server 2016 Express LocalDB | Microsoft Docs
Visual Studioから追加する。
サンプルプロジェクトはASP.NET MVC Webアプリケーションのルートから、マウス右クリックメニューから「追加」「SQLデータベース」 新しいDB名を追加 App_Dataフォルダーに追加するか聞かれるが、素直にApp_Dataにしました。
ソリューションにMyDbが追加される。
ログインパスワードを設定する。
mdfファイルをダブルクリックするとVisual Studio内のSQL Serverオブジェクトエクスプローラが開きます。
照合順序の変更
デフォルトは「SQL_Latin1_General_CP1_CI_AS」になっており、日本語が文字化けするので、「Japanese_XJIS_100_CI_AI_WS」へ変更が必要
Visual Studio内のSQL ServerオブジェクトエクスプローラからLocalDbを開いて、新しいクエリを表示し、以下のコマンドを実行する。
SELECT DB_NAME() GO -- 上記DB_NAMEをDB名にして実行 USE [master] GO ALTER DATABASE [database_name] COLLATE Japanese_XJIS_100_CI_AI_WS GO
テーブルに既にデータが貼っている場合
ALTER TABLE dbo.Table_1 ALTER COLUMN NAME varchar(50) COLLATE Japanese_XJIS_100_CI_AI_WS;
接続文字列
ASP.NET MVCのプロジェクト内部に入れた場合はフォルダー名を|DataDirectory|にすることが可能
Server=(LocalDB)\MSSQLLocalDB; Integrated Security=true ;AttachDbFileName=D:\Data\MyDB1.mdf Server=(LocalDB)\MSSQLLocalDB; Integrated Security=true ;AttachDbFileName=|DataDirectory|MyDB1.mdf
MS SQL Server Management Studioから接続する。
接続文字列に(LocalDB){インスタンス名}で接続出来る。
(LocalDB)\MSSQLLocalDB
インスタンス名がわからない場合、「sqllocaldb.exe」で調べられる。
> sqllocaldb info MSSQLLocalDB ProjectsV13
sqlcmdで接続する場合
新しいDB作成及び、ログインの手順…
恐らく、LocalDbをサーバーリリスする場合、サーバーのローカルユーザーからLocalDbを作成しないと権限問題が発生する可能性があり、 以下のコマンドからサーバーでLocalDbを作成するコマンドを実行する必要がありそう。 サーバーにもSQL Server Express LocalDbをインストールする必要あり。
SqlLocalDB.exe create "DeptLocalDB" SqlLocalDB.exe share "DeptLocalDB" "DeptSharedLocalDB" SqlLocalDB.exe start "DeptLocalDB" SqlLocalDB.exe info "DeptLocalDB" REM The previous statement outputs the Instance pipe name for the next step sqlcmd –S np:\\.\pipe\LOCALDB#<use your pipe name>\tsql\query CREATE LOGIN NewLogin WITH PASSWORD = 'Passw0rd!!@52'; GO CREATE USER NewLogin; GO EXIT
sqlcmd –S (localdb)\.\DeptSharedLocalDB -U NewLogin -P Passw0rd!!@52
参考: SqlLocalDB ユーティリティ | Microsoft Docs
ダウンロード: SQL Server Downloads | Microsoft