ハロの外部記憶インターフェイス

そろそろ覚える努力が必要かも…

ASP.NET MVC ファイルのダウンロード

ASP.NET MVCでファイルをダウンロードする方法メモ

Controller サーバーのフォルダにファイルが存在する場合

public ActionResult Download()
{
    var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    return File(Server.MapPath("~/App_Data/dummy.xlsx"), contentType, "download.xlsx");
}

FileStreamからダウンロード

public ActionResult Download()
{
     MemoryStream memoryStream = new MemoryStream();
     using (FileStream fileStream = new FileStream(FilePath, FileMode.Open, FileAccess.Read))
     {
       fileStream.CopyTo(memoryStream);
     }
    var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    return File(memoryStream.ToArray(), contentType, "download.xlsx");
}

IE11の互換モード使用で、表示がおかしくなる

IE11とEdgeでの表示が違う

今時ながらの事だが、IE11を使っている現場で、しかも互換モードが適用されているみたく、作ったページがおかしくなるらしい。

対策

HTMLのmetaタグに以下の内容を追加した

<meta http-equiv="X-UA-Compatible" content="IE=edge" />

とりあえず、直ったみたいなので、メモっとく

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;
}