ラベル C# の投稿を表示しています。 すべての投稿を表示
ラベル C# の投稿を表示しています。 すべての投稿を表示

2022年6月13日月曜日

ASP .NET Core(.NET6) RazorPagesでのFORMの値をクラス型でPostする

Personをクライアント側で動的に増減したいので
asp-forでbindするのではなく、idとnameを指定して
配列を受け取るようにしたい。

<ViewModel>

 public class Person

{

    public string? Name{get; set;}

    public Int32? Age{get;set;}

}


<RazorPages>

public IActionResult OnPostSave(Person[] person)
{

    //DataAnotationの実行はここで

    var success = true;

    foreach(var p in person)

    {

        success &= TryValidateModel(p);

    }

}


<cshtml>

<form id="frm" asp-route-handler="Save">

    <input id="person_Name" name="person[0].Name" type=~~ />

    <input id="person_Age" name="person[0].Age" type=~~ />

    <input id="person_Name" name="person[1].Name" type=~~ />

    <input id="person_Age" name="person[1].Age" type=~~ />

</form>


・覚えておくこと

inputタグのname属性を
OnPostSaveの引数パラメーター名 + [0からの要素番号] + .(ドット) + クラスのプロパティ名
とすること。

クライアントの検証は、$('#frm').validate().form()でできる。

2022年6月10日金曜日

ActiveReports16 .NET Core 6 RazorPagesでJSViewerを使う

・Nugetで追加

GrapeCity.ActiveReports.Aspnetcore.Viewer(16.0.2) を追加


・プロジェクトに追加

wwwroot/js/ に jsViewer.min.js

wwwroot/css/ に jsViewer.min.css

※これらは、npmで云々と記述されているが

公式からDLしたインストーラーでインストールした下記フォルダに入ってる。

~\Program Files(x86)\ActiveReportsNET16\Deployment\JSViewer


・Program.cs にレポート機能を追加を記述(青字部分)

using GrapeCity.ActiveReports.Aspnetcore.Viewer;


var builder = WebApplication.CreateBuilder(args);

~~ 略 ~~

var app = builder.Build();

~~ 略 ~~

app.UserStaticFiles();

app.UseReporting(settings =>

{
   settings.UseFileStore(new DirectoryInfo("サーバーのレポートファイルの場所"));

   settings.UseCompression = true;

});

~~ 略 ~~


・ページレポート(rdlx)を作成する

・レポートエクスプローラーのパラメータから追加する
 名前:ReportParameter1
 非表示にチェックONしておいた。
とする。

・レポートエクスプローラーのデータソースを追加
名前は適当
種類にJson Providerを指定
接続、接続文字列のタブに
「="jsondata=" & Parameters!ReportParameter1.Value」とする
赤字部分は、パラメータの名前にすること。

・データセットを追加
作成したデータソースにデータセットを追加する。
クエリに「$.[*]」を指定(これがないと、「コマンドテキストが空です。」と怒られる。
フィールドに必要な項目を追加。(名前は小文字の方がいいかも?)

・cshtmlに記述する

・jsとcssの参照を追加
<link rel="stylesheet" href="~/css/jsViewer.min.css" asp-append-version="true" />
<script src="~/js/jsViewer.min.js" asp-append-version="true"></script>

・HTML
<div id="previewcontainer"> </div>

・scriptタグの中
//elementはviewerを表示するdivのjQueryセレクタ
var viewer = GrapeCity.ActiveReports.JSViewer.create({
    element : '#previewcontainer',
    reportService: {
        url: '@(Url.Content("~/api/reporting"))'
    }
});

var jsondata = [{ "id": "1000", "name": "太郎"},{ "id": "1001", "name": "花子"}];
const  param = [
    {
        name: 'ReportParameter1',    //ページレポートのパラメータ名と一致させる
        values: [JSON.stringify(jsondata)]
    }
];
//ページレポート(rdlx)は、Program.csに指定したフォルダに入れておく

viewer.openReport("TEST.rdlx", param);


こんなもんだったと思う。

jsondataの取得部分をajaxでRazorPageにアクセスして取得。

JsonResultで返せばOK

2016年5月23日月曜日

catchしたExceptionの再スロー

C#でtry~catchを行うとき、catchブロックでthrowのみ書いてるソースがあったので
意味あんのか?ってことで調べてみた。

自分の認識では関数内のExceptionは最終的に.Net Frameworkが受けてくれるので
単にthrowするだけなら意味がないように思う。

ということで、スタックトレースがどう違うかを比べてみた。

①Hoge1~3はtry~catchを行わず、呼び出し元でtry~catchしてみる。
#region Hoge
private void button1_Click(object sender, EventArgs e)
{
    try
    {
        Hoge();
    }
    catch (Exception ex)
    {
        Console.WriteLine();
        Console.WriteLine("********Hoge*********");
        Console.WriteLine(ex.ToString());
    }
}

private void Hoge()
{
    Hoge1();
}


private void Hoge1()
{
    Hoge2();
}

private void Hoge2()
{
    Hoge3();
}

private void Hoge3()
{
    throw new DivideByZeroException();
}
#endregion

②Foo1~3はtry~catchを行ない、catch句ではthrow;のみする

#region Foo
private void button2_Click(object sender, EventArgs e)
{
    try
    {
        Foo();
    }
    catch (Exception ex)
    {
        Console.WriteLine();
        Console.WriteLine("********Foo*********");
        Console.WriteLine(ex.ToString());
    }
}

private void Foo()
{
    try
    {
        Foo1();
    }
    catch
    {
        throw;
    }
}

private void Foo1()
{
    try
    {
        Foo2();
    }
    catch
    {
        throw;
    }
}

private void Foo2()
{
    try
    {
        Foo3();
    }
    catch
    {
        throw;
    }
}

private void Foo3()
{
    throw new DivideByZeroException();
}
#endregion
③Func1~3はtry~catchを行ない、catch句ではthrowされたExceptionをさらにthrowする
#region Func
private void button3_Click(object sender, EventArgs e)
{
    try
    {
        Func();
    }
    catch (Exception ex)
    {
        Console.WriteLine();
        Console.WriteLine("********Func*********");
        Console.WriteLine(ex.ToString());
    }
}

private void Func()
{
    try
    {
        Func1();
    }
    catch (DivideByZeroException ex)
    {
        throw ex;
    }
}

private void Func1()
{
    try
    {
        Func2();
    }
    catch (DivideByZeroException ex)
    {
        throw ex;
    }
}

private void Func2()
{
    try
    {
        Func3();
    }
    catch(DivideByZeroException ex)
    {
        throw ex;
    }
}

private void Func3()
{
    throw new DivideByZeroException();
}
#endregion

結果

********Hoge*********
System.DivideByZeroException: 0 で除算しようとしました。
   場所 WindowsFormsApplication1.Form1.Hoge3() 場所 D:\94_DevelopVS\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:行 53
   場所 WindowsFormsApplication1.Form1.Hoge2() 場所 D:\94_DevelopVS\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:行 48
   場所 WindowsFormsApplication1.Form1.Hoge1() 場所 D:\94_DevelopVS\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:行 43
   場所 WindowsFormsApplication1.Form1.Hoge() 場所 D:\94_DevelopVS\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:行 37
   場所 WindowsFormsApplication1.Form1.button1_Click(Object sender, EventArgs e) 場所 D:\94_DevelopVS\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:行 25
例外がスローされました: 'System.DivideByZeroException' (WindowsFormsApplication1.exe の中)
例外がスローされました: 'System.DivideByZeroException' (WindowsFormsApplication1.exe の中)
例外がスローされました: 'System.DivideByZeroException' (WindowsFormsApplication1.exe の中)
例外がスローされました: 'System.DivideByZeroException' (WindowsFormsApplication1.exe の中)


結果

 ********Foo*********
System.DivideByZeroException: 0 で除算しようとしました。
   場所 WindowsFormsApplication1.Form1.Foo3() 場所 D:\94_DevelopVS\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:行 110
   場所 WindowsFormsApplication1.Form1.Foo2() 場所 D:\94_DevelopVS\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:行 104
   場所 WindowsFormsApplication1.Form1.Foo1() 場所 D:\94_DevelopVS\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:行 92
   場所 WindowsFormsApplication1.Form1.Foo() 場所 D:\94_DevelopVS\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:行 80
   場所 WindowsFormsApplication1.Form1.button2_Click(Object sender, EventArgs e) 場所 D:\94_DevelopVS\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:行 62
例外がスローされました: 'System.DivideByZeroException' (WindowsFormsApplication1.exe の中)
例外がスローされました: 'System.DivideByZeroException' (WindowsFormsApplication1.exe の中)
例外がスローされました: 'System.DivideByZeroException' (WindowsFormsApplication1.exe の中)
例外がスローされました: 'System.DivideByZeroException' (WindowsFormsApplication1.exe の中)

③結果

********Func*********
System.DivideByZeroException: 0 で除算しようとしました。
   場所 WindowsFormsApplication1.Form1.Func() 場所 D:\94_DevelopVS\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:行 137
   場所 WindowsFormsApplication1.Form1.button3_Click(Object sender, EventArgs e) 場所 D:\94_DevelopVS\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:行 119



■結論
ということで、 catch句で何かしらの処理を行うならアリだが、単にthrow;だけなら不要。
③のパターンはスタックトレースが最後のthrow分しか残ってないので最悪。

普通に①でやるのがよさげ。

2015年9月2日水曜日

System.IO.Directory.Deleteの不思議現象

1.フォルダを削除
2.フォルダを作成

として、一括でフォルダをクリアしたいときってあるよね。

以下のコードを実行したところ、フォルダが作成されない現象に陥った。


if(Directory.Exists(path))
{
    Directory.Delete(path, true);
}

Directory.CreateDirectory(path);


//ここでフォルダが存在しない



VSをデバッグで1行ずつ進めると、きっちり削除されて作成される。



以下のように変更してみた。 


if(Directory.Exists(path))
{
    Directory.Delete(path, true);
}

Int32 n = 0;

while(Directory.Exists(path))
{

    n++;
}


Console.WriteLine(n);

Directory.CreateDirectory(path);
 //こうすると確実に作成される。
//nは2とか1とかになる。

普通に考えるとDelete()が実行された時点でpathのフォルダは存在しないはず
なので、n==0になると思ったが、n==2となり、2ループ分path存在したことを示している。

この現象は別のPCでは発生しない場合もある。 

調べてみたところ、MSDNに書いてあった。

MSDN Directory.Delete メソッド (String, Boolean) 

In some cases, if you have the specified directory open in File Explorer, the Delete method may not be able to delete it.
ある場合において、あなたが指定したディレクトリをエクスプローラーで開いていると、Deleteメソッドは、削除することができない場合があります。

ガ━━(;゚Д゚)━━ン!!

たしかに、エクスプローラーで該当フォルダを開きながら 実行していた。
エクスプローラーを閉じて、下のプログラムを実行するとnの結果は0となった。

ていうか”ある場合”って何よ。
そこをハッキリしなさいよ!

2013年10月2日水曜日

Active Reportを含むプロジェクトをTFSでビルド

active reportをインストールした端末にtfsをインストールしないとできなさそう。
・active reportをインストール
・それぞれのプロジェクトにlicxファイルを追加
・TFSのビルド定義で
  1.プロセス→3.詳細→MSBuildプラットフォームをX86
  2.エージェントの設定にactive reportをインストールした端末のエージェントを設定

※追記
TFSをインストールしているサーバーにActive Reportsをインストールするには
ライセンスが必要になるので、すでにActive Reportsをインストールしている
開発PCをTFSのビルドエージェントとして登録すると、サーバーにActive Reportsを
インストールしなくてすむ。

2013年2月14日木曜日

Active Reportsを動作させるWEBサーバー設定

プリンタの用紙設定は、ActiveReportsを起動するユーザーの
用紙設定を使用する模様。

サービスから起動する場合は、そのサービスユーザーの用紙設定がいる。

2013年1月26日土曜日

Windowsサービスの登録方法

C:\Windows\Microsoft.NET\Framework\v4.0.30319>installutil [サービスexe]

.NET2のフォルダにもInstallutilがある。
作ったサービスとバージョンを合わせる必要がありそう。

2013年1月5日土曜日

ブーストラップパッケージ作成用再配布モジュールの展開

hVisual Studio 2010では、.NET4アプリのセットアッププロジェクトは当然すぐに作れるが、.NET3.5以下のアプリケーションのセットアッププロジェクトではパッケージ用のモジュールがないので、前述の[アプリケーションと同じ場所から必須コンポーネントをダウンロードする]にした場合は、パッケージ用のモジュールを自分で用意する必要がある。

1.以下のページ内の「.NET Framework 3.5 Service Pack 1 (完全なパッケージ)」をクリックして、.NET Framework3.5 SP1をダウンロードする。
 Microsoft .NET Framework 3.5 Service Pack 1

2.コマンドプロンプトで解凍する。
 > dotnetfx35.exe /x

3.解凍するとWCUフォルダ配下に以下の内容が展開される。
 dotNetFX20
 dotNetFX30
 dotNetFX35
 dotNetMSP
 TOOLS
 dotNetFx35setup.exe

4.これらの5フォルダ、1ファイルを以下のフォルダにコピーする。
 %Program Files%Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\DotNetFX35SP1

※Windows10 x64 Visual Studio 2017では
C:¥Program Files(x86)¥Microsoft SDKs¥ClickOnce Boostrapper¥Packagesの配下だった

5.以下のサイトから Laguage Packをダウンロードする。
 Microsoft .NET Framework 3.5 日本語 Language Pack

6.5.でダウンロードしたファイルは
 %Program Files%Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\DotNetFX35SP1\ja
 の中のDotNetFX35\x86またはx64にそれぞれコピーする。

※Windows10 x64 Visual Studio 2017では
C:¥Program Files(x86)¥Microsoft SDKs¥ClickOnce Boostrapper¥Packages¥jaの配下にコピー

2012年12月19日水曜日

2012年12月17日月曜日

DataContractのstring以外のプリミティブ値のDataMember定義

[DataMember(IsRequired = true)]
にしないとサービス側に受け渡されない。

Containerを含むUserControlで、上に置いたControlが消える

UserControlの上にPanel等のコンテナを配置すると、UserControl使用の際に
Panel等の背面に置いたコントロールが行ってしまう。

UserControlの上にPanel等のコンテナを配置しないか
なんかいろいろするとできるらしい。

DataContractの参照設定

Client側では、DataContractクラスへの直接の参照は不要。
Visualスタジオのプロキシクラス作成時に自動的に作成されるクラスを使用するため。