SQLの窓

2017年08月06日


C#(VS2010) : dynamic 型を使用して CreateObject と同等に Scripting.FileSystemObject を使用する

ボタンを一つフォームに貼って、固定パスの SHIFT_JIS テキストファイルを読み込んでいます。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WinFormsApp1 {
	public partial class Form1 : Form {

		private dynamic objFile;

		public Form1() {
			InitializeComponent();
		}

		private void button1_Click(object sender, EventArgs e) {

			string buffer;
			try {
				dynamic inFile = objFile.OpenTextFile(@"c:\tmp\help.txt", 1);
				while (!inFile.AtEndOfStream) {
					buffer = inFile.ReadLine();
					Console.Out.WriteLine(buffer);
				}
				inFile.close();
			}
			catch (Exception ex) {
				MessageBox.Show("ファイルが存在しません");
			}

		}

		private void Form1_Load(object sender, EventArgs e) {

			objFile = Activator.CreateInstance(Type.GetTypeFromProgID("Scripting.FileSystemObject"));

		}

		private void Form1_FormClosed(object sender, FormClosedEventArgs e) {

			System.Runtime.InteropServices.Marshal.ReleaseComObject(objFile);

		}
	}
}


参考ページ

C#でCreateObjectと同じことをするには?(dobon.net) のコメント部分

dynamic 型の使用(docs.microsoft.com)



タグ:VS C#
posted by lightbox at 2017-08-06 22:04 | Comment(0) | VS(C#) | このブログの読者になる | 更新情報をチェックする

2017年06月03日


VS(C#) : DataGrid に バインドを使用して JSON データの配列を表示する( Json.NET を使用 )



JSON 文字列を Json.NET で一行でデシリアライズします。その際、バインド用の ObservableCollection に直接セットするので、DataGrid には、DataContext にセットするだけで、表示用の列と行は自動作成されます

外部ライブラリ

JSON データの扱いには、Json.NET を使用します。ダウンロードして、Bin フォルダにある自分の環境に該当するフレームワークフォルダを ソリューションの中に置いて参照設定を行います。
※ net45 フォルダをコピーして使用しました / VS2012

JSON データ

https://lightbox.sakura.ne.jp/demo/json/syain_json.php

このデータを扱う為に以下のクラスを作成しています

Syain.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfAppDataGridFromWeb {
	class Syain {
		public string 社員コード { get; set; }
		public string 氏名 { get; set; }

		public string フリガナ { get; set; }
		public string 所属 { get; set; }

		private string _性別;
		public string 性別 {
			get {
				if (this._性別 == "0") {
					return "男";
				}
				else {
					return "女";
				}
			}
			set {
				this._性別 = value;
			}
		}
		public int 給与 { get; set; }
		public int? 手当 { get; set; }
		public string 管理者 { get; set; }

		public string 作成日 { get; set; }
		public string 更新日 { get; set; }

	}
}


画面

デフォルトで True になっていますが、バインドで列を自動作成させる為に 『AutoGenerateColumns="True"』を DataGrid に設定しています
<Window
	x:Class="WpfAppDataGridFromWeb.MainWindow"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	Title="MainWindow"
	Height="857.456"
	Width="1191.774">
	<Grid>
		<Button
			Content="Button"
			HorizontalAlignment="Left"
			Height="24"
			Margin="27,29,0,0"
			VerticalAlignment="Top"
			Width="122"
			Click="Button_Click" />
		<DataGrid
			x:Name="dataGrid"
			HorizontalAlignment="Left"
			Height="720"
			Margin="27,71,0,0"
			VerticalAlignment="Top"
			Width="1124"
			ItemsSource="{Binding}"
			IsReadOnly="True"
			MouseDoubleClick="dataGrid_MouseDoubleClick" />

	</Grid>
</Window>


処理
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.Odbc;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfAppDataGridFromWeb {

	public partial class MainWindow : Window {

		public MainWindow() {
			InitializeComponent();
			// ウインドウを中央へ
			this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
		}

		private void Button_Click(object sender, RoutedEventArgs e) {

			dataGrid.Columns.Clear();

			Console.WriteLine("クリックされました");
			Console.WriteLine(Directory.GetCurrentDirectory());

			string url = "https://lightbox.sakura.ne.jp/demo/json/syain_json.php";
			string result = "[\"error\"]";

			// 信頼性のある WebClient で インターネットアクセス
			WebClient wc = new System.Net.WebClient();
			wc.Encoding = System.Text.Encoding.UTF8;
			try {
				// 読み込み
				result = wc.DownloadString(url);
			}
			catch( Exception ex) {
				Console.WriteLine("WebClient エラー:" + ex.ToString());
			}

			// JSON オブジェクト配列 Newtonsoft.Json( net45 )
			ObservableCollection<Syain> syain_data = JsonConvert.DeserializeObject<ObservableCollection<Syain>>(result);
			// DataGrid にバインド
			dataGrid.DataContext = syain_data;

		}

		// DataGrid をダブルクリックした時の行データの取得
		private void dataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
			int row = dataGrid.SelectedIndex;
			if ( row >= 0 ) {
				Syain syain = (Syain)dataGrid.Items.GetItemAt(row);
				Debug.WriteLine(syain.社員コード + "|" + syain.氏名);

				MessageBox.Show(syain.社員コード + "|" + syain.氏名,
					"確認",
					MessageBoxButton.OK,
					MessageBoxImage.Information);
			}
		}

	}
}

※ HttpClient はバグがあるという話なので使用していません。

関連する記事

Swing の JTable に 1) WEBのJSON2次元配列。2) WEB の JSON配列 を取り込んで表示する( Google Gson と okhttp を使用 )

補足

以下の例では、AutoGenerateColumns="False" に設定して、列の定義をプログラムで行っています。このほうがアプリケーションとしては、列単位で仕様を決定しやすいので自由度が増すはずです。

※ データは JSON の2次元配列を使用しています
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.Odbc;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfAppDataGridFromWeb {

	public partial class MainWindow : Window {

		private DataGridTextColumn col;
		private ObservableCollection<Syain> syain_list = null;

		public MainWindow() {
			InitializeComponent();
			// ウインドウを中央へ
			this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
		}

		private void Button_Click(object sender, RoutedEventArgs e) {

			dataGrid.Columns.Clear();

			Console.WriteLine("クリックされました");
			Console.WriteLine(Directory.GetCurrentDirectory());

			string url = "https://lightbox.sakura.ne.jp/demo/json/syain_array.php";
			string result = "[\"error\"]";

			// 信頼性のある WebClient で インターネットアクセス
			WebClient wc = new System.Net.WebClient();
			wc.Encoding = System.Text.Encoding.UTF8;
			try {
				// 読み込み
				result = wc.DownloadString(url);
			}
			catch( Exception ex) {
				Console.WriteLine("WebClient エラー:" + ex.ToString());
			}

			// JSON 2次元配列 Newtonsoft.Json( net45 )
			string[][] syain_data = JsonConvert.DeserializeObject<string[][]>(result);

			// バインド用クラス
			Syain syain;
			// 列用
			col = null;
			// バインド用コレクション
			syain_list = new ObservableCollection<Syain>();

			foreach (string[] syain_row in syain_data) {

				// 初回
				if (col == null) {
					foreach (string syain_col in syain_row) {
						col = new DataGridTextColumn();
						col.Header = syain_col;
						col.Binding = new Binding(syain_col);
						dataGrid.Columns.Add(col);
					}
					continue;
				}

				syain = new Syain();
				syain.社員コード = syain_row[0];
				syain.氏名 = syain_row[1];
				syain.フリガナ = syain_row[2];
				syain.所属 = syain_row[3];
				syain.性別 = syain_row[4];
				syain.給与 = int.Parse(syain_row[7]);
				syain.手当 = (syain_row[8] == "" ? 0 : int.Parse(syain_row[8]));
				syain.管理者 = syain_row[9];
				syain.作成日 = syain_row[5];
				syain.更新日 = syain_row[6];
				// observablecollection に追加
				syain_list.Add(syain);

			}

			//// DataGrid にバインド
			dataGrid.DataContext = syain_list;

		}

		// DataGrid をダブルクリックした時の行データの取得
		private void dataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
			int row = dataGrid.SelectedIndex;
			if ( row >= 0 ) {
				Syain syain = (Syain)dataGrid.Items.GetItemAt(row);
				Debug.WriteLine(syain.社員コード + "|" + syain.氏名);

				MessageBox.Show(syain.社員コード + "|" + syain.氏名,
					"確認",
					MessageBoxButton.OK,
					MessageBoxImage.Information);
			}
		}

	}
}




タグ:C# Json.NET JSON
posted by lightbox at 2017-06-03 20:31 | Comment(0) | VS(C#) | このブログの読者になる | 更新情報をチェックする

2017年04月18日


csc.exe を使用して、コマンドプロンプトから C# 5 のアプリケーションをビルドする



32ビット用 : %windir%\Microsoft.NET\Framework\v4.0.30319
64ビット用 : %windir%\Microsoft.NET\Framework64\v4.0.30319

以下64ビット環境です。
※ Windows10 でも動作していますが、以下のメッセージが出力されます
This compiler is provided as part of the Microsoft (R) .NET Framework, but only supports language versions up to C# 5, which is no longer the latest version.
csc.exe は、c# 用のコンパイラです。面倒な場所ではあるので、以下のスクリプトで簡単にプロンプトが作成できます
<JOB>
<RESOURCE id="commandList">
<![CDATA[
mode con: cols=120
set PATH=%windir%\Microsoft.NET\Framework64\v4.0.30319;%PATH%
prompt C#$G
]]>
</RESOURCE>

<OBJECT id="WshShell" progid="WScript.Shell" />
<OBJECT id="Fso" progid="Scripting.FileSystemObject" />

<SCRIPT language=VBScript>
' ***********************************************************
' 処理開始
' ***********************************************************

strPath = WScript.ScriptFullName
Set obj = Fso.GetFile( strPath )
Set obj = obj.ParentFolder
WshShell.CurrentDirectory = obj.Path

aData = Split( GetInline( "commandList" ), vbCrLf )
strCommand = "cmd.exe /k " & aData(0)
For I = 1 to Ubound( aData )
	strCommand = strCommand & "&" & aData(I)
Next
Call WshShell.Run( strCommand, 3 )

' ***********************************************************
' 関数
' ***********************************************************
Function GetInline( strName )

	GetInline = RegTrim( getResource( strName ) ) & vbCrLf

End Function
Function RegTrim( strValue )

	Dim regEx, str

	Set regEx = New RegExp
	regEx.IgnoreCase = True
	regEx.Pattern = "^[ \s]+"
	str = regEx.Replace( strValue, "" )
	regEx.Pattern = "[ \s]+$"
	RegTrim = regEx.Replace( str, "" )

End Function
</SCRIPT>
</JOB>

VBScript で記述されており、通常エクスプローラから実行すると最大化ウインドウでコマンドプロンプトが開くように作成してあります。

コマンドプロンプトからは、csc ソースコード.cs と入力するだけで基本的なビルドはすぐできます。

sample.cs
using System;
using System.IO;

// ********************************************************
// 実行
// ********************************************************
public class App
{

	public static void Main() {

		// PATH 環境変数取得
		String strEnv = Environment.GetEnvironmentVariable( "PATH" );

		// 配列定義
		String delimStr = ";";
		Char[] delimiter = delimStr.ToCharArray();

		String[] split = null;

		// トークン分割
		split = strEnv.Split( delimiter );

		// ソート
		Array.Sort( split, split.GetLowerBound(0), split.Length );

		// 書き込み
		try {
			StreamWriter OutFile = new StreamWriter( @".\result.txt", false );
			foreach (String strValue in split) {
				OutFile.WriteLine( strValue );
			}
			OutFile.Flush();
			OutFile.Close();
	
		}
		catch( Exception e ) {
			Console.WriteLine("エラーの内容 : {0}", e.ToString());
		}
	}

}

オプションは csc /? で表示されます。

mysql.cs( ODBC アクセス )
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Data.Odbc;

public class App
{

	// ********************************************************
	// MySQL / System.Data.Odbc
	// ********************************************************

	public static void Main()
	{
		string myConnectString = "Driver={MySQL ODBC 5.3 Unicode Driver};" + "SERVER=localhost;" + "DATABASE=lightbox;" + "UID=root;" + "PWD=password";

		OdbcConnection myCon = new OdbcConnection();
		myCon.ConnectionString = myConnectString;
		myCon.Open();

		string myQuery = "SELECT 社員マスタ.*,DATE_FORMAT(生年月日,'%Y-%m-%d') as 誕生日" + " from 社員マスタ";
		OdbcCommand myCommand = new OdbcCommand();
		myCommand.CommandText = myQuery;
		myCommand.Connection = myCon;

		OdbcDataReader myReader = default(OdbcDataReader);
		myReader = myCommand.ExecuteReader();


		while (myReader.Read()) {
			// 文字列
			Console.Write(GetValue(myReader, "社員コード") + " : ");
			Console.Write(GetValue(myReader, "氏名") + " : ");

			// 整数
			Console.Write(GetValue(myReader, "給与") + " : ");

			// 日付
			Console.Write(GetValue(myReader, "作成日") + " : ");
			Console.Write(GetValue(myReader, "更新日") + " : ");
			Console.Write(GetValue(myReader, "生年月日") + " : ");
			Console.Write(GetValue(myReader, "誕生日"));
			Console.WriteLine();

		}

		myReader.Close();

		myQuery = "update 社員マスタ set 生年月日 = '1982/01/01'" + " where 社員コード = '0002'";
		Execute(myCon, myQuery);

		myCon.Close();

		myReader.Dispose();
		myCon.Dispose();

	}

	// ********************************************************
	// 列データ取得
	// ********************************************************
	public static string GetValue(OdbcDataReader odr, string strName)
	{

		string ret = "";
		int fld = 0;

		fld = odr.GetOrdinal(strName);
		if (odr.IsDBNull(fld)) {
			ret = "";
		} else {
			ret = odr.GetValue(fld).ToString();
		}

		return ret;

	}

	// ********************************************************
	// 更新処理
	// ********************************************************
	public static int Execute(OdbcConnection cn, string SQL)
	{

		int ret = 0;
		OdbcCommand execCommand = new OdbcCommand();

		execCommand.CommandText = SQL;
		execCommand.Connection = cn;
		try {
			ret = execCommand.ExecuteNonQuery();
		} catch (Exception ex) {
			Console.WriteLine(ex.Message);
		}
		execCommand.Dispose();

		return ret;

	}

}




タグ:C#
posted by lightbox at 2017-04-18 22:08 | Comment(0) | VS(C#) | このブログの読者になる | 更新情報をチェックする

2016年07月01日


キネクトでブラウザを動かす

必要なもの

1) キネクト
2) Visual Studio
3) Kinect for Windows SDK v1.7
4) Kinect PowerPoint Control

Kinect PowerPoint Control の概要

結局のところ、Kinect の基本的な機能のとても簡単なサンプルです( 音声認識部分もありますが、日本語がどうかわからないので試していません )。
Power Point での使用を想定して作られたようですが、右手が頭より、X 軸で(外側に) 45センチ離れたら 右矢印キーを押し、左手が頭より、X 軸で(外側に) 45センチ離れたら 左矢印キーを押すという機能のみ実装されています。

ここでは、3箇所しか認識させていませんが、同様にして 20箇所の人体の部分を認識可能です。

なので、少しコードを触るだけで、ジェスチャーによるキーコマンドをいくつでも追加できます。そして、ブラウザ側では、jQuery を使って .keydown で受ければいろいろな画面展開が可能になるでしょう。

コマンド受付部分(ここを改造)
        private void ProcessForwardBackGesture(Joint head, Joint rightHand, Joint leftHand)
        {
            // 頭と右手が x 座標で 45 センチ離れた場合に 右矢印キーを押した事にする
            if (rightHand.Position.X > head.Position.X + 0.45)
            {
                if (!isForwardGestureActive)
                {
                    isForwardGestureActive = true;
                    System.Windows.Forms.SendKeys.SendWait("{Right}");
                }
            }
            else
            {
                isForwardGestureActive = false;
            }

            // 頭と左手が x 座標で 45 センチ離れた場合に 左矢印キーを押した事にする
            if (leftHand.Position.X < head.Position.X - 0.45)
            {
                if (!isBackGestureActive)
                {
                    isBackGestureActive = true;
                    System.Windows.Forms.SendKeys.SendWait("{Left}");
                }
            }
            else
            {
                isBackGestureActive = false;
            }
        }

※ 各コマンド用のフラグは MainWindow クラスの変数として追加定義します

実際動かすと良く解りますが、頭と手が認識されると赤い丸が表示され、コマンドを送れる位置に移動すると大きな緑の丸に変化します。コマンドは、いったん赤い丸に戻してからでないと、再度実行する事はできません。

また、認識には少なくとも 150センチ離れる必要があり、C キーで認識円の表示を消す事ができるようです。

画面定義
<Window x:Class="KinectPowerPointControl.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Kinect PowerPoint Control"
        Height="480"
        Width="640"
        WindowState="Maximized">
    <Viewbox Stretch="Uniform">
        <Grid>
            <Image Name="videoImage"
                   Width="640"
                   Height="480"></Image>
            <Canvas Background="Transparent">
                <Ellipse Fill="Red"
                         Height="20"
                         Width="20"
                         Name="ellipseLeftHand"
                         Stroke="White" />
                <Ellipse Fill="Red"
                         Height="20"
                         Width="20"
                         Name="ellipseRightHand"
                         Stroke="White" />
                <Ellipse Fill="Red"
                         Height="20"
                         Width="20"
                         Name="ellipseHead"
                         Stroke="White" />
            </Canvas>
        </Grid>
    </Viewbox>
</Window>

※ videoImage に、映像が表示され、最初左上に赤い丸が表示されています。

プログラムの中核となる部分
        void sensor_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            using (var skeletonFrame = e.OpenSkeletonFrame())
            {
                if (skeletonFrame == null)
                    return;

                if (skeletons == null ||
                    skeletons.Length != skeletonFrame.SkeletonArrayLength)
                {
                    skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
                }

                skeletonFrame.CopySkeletonDataTo(skeletons);
            }

            Skeleton closestSkeleton = skeletons.Where(s => s.TrackingState == SkeletonTrackingState.Tracked)
                                                .OrderBy(s => s.Position.Z * Math.Abs(s.Position.X))
                                                .FirstOrDefault();

            if (closestSkeleton == null)
                return;

            // 頭
            var head = closestSkeleton.Joints[JointType.Head];
            // 右手
            var rightHand = closestSkeleton.Joints[JointType.HandRight];
            // 左手
            var leftHand = closestSkeleton.Joints[JointType.HandLeft];

            // NotTracked : 追跡していない
            if (head.TrackingState == JointTrackingState.NotTracked ||
                rightHand.TrackingState == JointTrackingState.NotTracked ||
                leftHand.TrackingState == JointTrackingState.NotTracked)
            {
                //Don't have a good read on the joints so we cannot process gestures
                return;
            }

            // MainWindow.xaml に定義された ellipse
            SetEllipsePosition(ellipseHead, head, false);
            SetEllipsePosition(ellipseLeftHand, leftHand, isBackGestureActive);
            SetEllipsePosition(ellipseRightHand, rightHand, isForwardGestureActive);

            ProcessForwardBackGesture(head, rightHand, leftHand);
        }


二つのフラグが立って初めてコマンドを送れるようにも出来ますし、20箇所の場所を使えばいろいろかなりコマンドを作れると思います。また、ブラウザ上の位置とキネクトの座標とを同期させてコマンドを発動する事もできるでしょう。




posted by lightbox at 2016-07-01 07:31 | Comment(0) | VS(C#) | このブログの読者になる | 更新情報をチェックする

2014年10月04日


Windows SDK の mt.exe を使用して、既存の exe を常に管理者権限で起動を求めるように変更する

テストしたのは、TeraPad.exe です。ショートカットアイコンを作成するとこんなアイコンになりました。



マニフェストファイルの作成

TeraPad.exe と同じディレクトリに、TeraPad.exe.manifest を作成して以下のような内容を書き込みます
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"  
    manifestVersion="1.0"> 
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> 
    <security> 
        <requestedPrivileges> 
        <requestedExecutionLevel 
        level="requireAdministrator"/> 
        </requestedPrivileges> 
    </security> 
    </trustInfo> 
</assembly>

これに関しては、アプリケーション開発者向け Microsoftレジスタードマーク Windows 7 対応アプリケーションの互換性 で記述されています。

mt.exe で manifest を埋め込めるという事が上記リンクに書かれてあったので、試してみました。コマンドラインは以下のようになっています。
"C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\mt.exe" -manifest TeraPad.exe.manifest -outputresource:TeraPad.exe
このコマンドラインは、『マニフェストを C/C++ アプリケーションに埋め込む』に書かれています。

変更した exe と 元の exe を fc /b で比較すると、確かに違うものである事が確認されました。さらに、変更された exe を他の場所にコピーして実行しても、管理者である事を確認する『暗転+ダイアログ表示』が実行されることが確認できました。

インストール直後から管理者マーク

つまり、ビルド時にすでにそのような要件の元作成されているアプリケーションは、自動的に管理者の盾マークが表示されているので、それを削除する事は通常できません。



posted by lightbox at 2014-10-04 22:11 | VS(C#) | このブログの読者になる | 更新情報をチェックする

2014年09月18日


VS(C#) : Json.NET を使用して文字列形式の JSON をプログラムで参照する具体的な方法

一番可読性の良い、管理しやすい方法は、JSON のフォーマットと同じ項目を持つ『クラス』を作成して一括変換する方法です。JSON の中の階層は、そのまま実装するクラスの中で配列にしたり、さらに細かいクラスを作成して対応します。

手っ取り早い方法は、JObject にパースして、JavaScript 内で参照する方法と同じ書式で参照します。いずれにしても、JavaScript との連携になる場合も考えて、どちらを使うかを決定すればいいと思います。

テスト用 JSON
{
    "id": 91500526,
    "simple_array": [1,2,3,4,5],
    "object_array": [
        {"high":1,"middle":2,"low":3},
        {"high":21,"middle":22,"low":23},
        {"high":31,"middle":32,"low":33}
    ],
    "object_data": {"sworc":"lightbox"},
    "profile_background_tile": false,
    "notifications": false,
    "profile_sidebar_fill_color": "FFF7CC",
    "location": "\u5927\u962a\u5e9c",
    "screen_name": "sworc",
    "profile_image_url": "http:\/\/a0.twimg.com\/profile_images\/2388651010\/zmq5cwm5nsvngpfrtr3f_normal.png"
}
クラスを使った一括変換

元々の JSON に合うフォーマットのクラスを事前に作成して、JsonConvert.DeserializeObject<クラス名>(文字列); で変換します。後は、クラスとして参照するだけです。

Serializing Collections,Deserializing Collections,Deserializing Dictionaries

JObject を使った参照

JObject jo = JObject.Parse(文字列); を実行して、jo を使って参照します。実際の JavaScript と同様の ["文字列"] 形式でプロパティを参照して行きます
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;

namespace Json130906
{
    class Program
    {
        static string hl = "-----------------------------------------------------";
        static string json = null;
        static void Main(string[] args)
        {
            // 処理全体を簡単に try 〜 catch する為に
            JsonTest jt = new JsonTest();
            try
            {
                jt.Test();

                Console.WriteLine(hl);
                Console.ReadLine();
                // ******************************************
                // クラスを使った一括変換
                // ******************************************
                MyJson data = JsonConvert.DeserializeObject<MyJson>(json);
                Console.WriteLine(data.id.ToString());
                Console.Write(
                    "{0}:{1}:{2}:{3}:{4}\n{5}:{6}:{7}\n{8}:{9}:{10}\n{11}:{12}:{13}\n",
                    data.simple_array[0].ToString(),
                    data.simple_array[1].ToString(),
                    data.simple_array[2].ToString(),
                    data.simple_array[3].ToString(),
                    data.simple_array[4].ToString(),
                    data.object_array[0].high.ToString(),
                    data.object_array[0].middle.ToString(),
                    data.object_array[0].low.ToString(),
                    data.object_array[1].high.ToString(),
                    data.object_array[1].middle.ToString(),
                    data.object_array[1].low.ToString(),
                    data.object_array[2].high.ToString(),
                    data.object_array[2].middle.ToString(),
                    data.object_array[2].low.ToString()
                );
                Console.WriteLine(data.object_data["sworc"]);
                Console.WriteLine(data.profile_background_tile);
                Console.WriteLine(data.notifications);
                Console.WriteLine(data.profile_sidebar_fill_color);
                Console.WriteLine(data.location);
                Console.WriteLine(data.screen_name);
                Console.WriteLine(data.profile_image_url);

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.WriteLine(hl);
            Console.WriteLine("処理を終了しました");
            Console.ReadLine();

        }

        // ******************************************
        // 処理用クラス
        // ******************************************
        private class JsonTest
        {
            public void Test() {
                // 簡単なエントリと、単純配列と、オブジェクト配列を含んだ JSON
                string url = "http://toolbox.winofsql.jp/json/sample1.json";

                // HTTP でのアクセス
                WebClient wc = new WebClient();
                // UTF-8 として取得
                wc.Encoding = Encoding.UTF8;
                // 文字列として取得
                json = wc.DownloadString(url);

                // コマンドプロンプト上に表示して一旦停止
                Console.WriteLine(json);
                Console.WriteLine(hl);
                Console.ReadLine();

                // ******************************************
                // 文字列から JObject を作成
                // ******************************************
                JObject jo = JObject.Parse(json);

                // JProperty で 一覧表示
                foreach (JProperty jp in jo.Properties())
                {
                    // 下位にデータがある場合は、Array または Object と表示されます
                    Console.WriteLine("タイプ : " + jp.Value.Type.ToString());
                    // 一番上位レベルに対する値を文字列で表示
                    Console.WriteLine(jp.Name + " --> " + jp.Value.ToString());
                }

                // コマンドプロンプト上で一旦停止
                Console.WriteLine(hl);
                Console.ReadLine();

                string[] key = {
                               "id","simple_array","object_array","object_data",
                               "profile_background_tile",
                                "notifications",
                                "profile_sidebar_fill_color",
                                "location",
                                "screen_name",
                                "profile_image_url"
                           };

                // JObject でキーを指定して直接参照
                foreach (string value in key)
                {
                    Console.WriteLine(jo[value].ToString());
                }

                // コマンドプロンプト上で一旦停止
                Console.WriteLine(hl);
                Console.ReadLine();

                // ******************************************
                // 下位階層単純配列の直接参照
                // ******************************************
                Console.WriteLine(jo["simple_array"][0].ToString());
                Console.WriteLine(jo["simple_array"][1].ToString());
                Console.WriteLine(jo["simple_array"][2].ToString());
                Console.WriteLine(jo["simple_array"][3].ToString());
                Console.WriteLine(jo["simple_array"][4].ToString());

                // ******************************************
                // 下位階層オブジェクト配列の直接参照
                // ******************************************
                Console.WriteLine(jo["object_array"][0]["high"].ToString());
                Console.WriteLine(jo["object_array"][0]["middle"].ToString());
                Console.WriteLine(jo["object_array"][0]["low"].ToString());
                Console.WriteLine(jo["object_array"][1]["high"].ToString());
                Console.WriteLine(jo["object_array"][1]["middle"].ToString());
                Console.WriteLine(jo["object_array"][1]["low"].ToString());
                Console.WriteLine(jo["object_array"][2]["high"].ToString());
                Console.WriteLine(jo["object_array"][2]["middle"].ToString());
                Console.WriteLine(jo["object_array"][2]["low"].ToString());

                // ******************************************
                // 下位階層オブジェクト直接参照
                // ******************************************
                Console.WriteLine(jo["object_data"]["sworc"].ToString());

            }
        }

        // ******************************************
        // 一括変換用のクラス
        // ******************************************
        private class MyJson
        {
            public int id { get; set; }
            public int[] simple_array { get; set; }
            public Object_Array[] object_array { get; set; }
            public JObject object_data { get; set; }
            public string profile_background_tile  { get; set; }
            public string notifications  { get; set; }
            public string profile_sidebar_fill_color  { get; set; }
            public string location  { get; set; }
            public string screen_name  { get; set; }
            public string profile_image_url { get; set; }
        }
        private class Object_Array
        {
            public int high { get; set; }
            public int middle { get; set; }
            public int low { get; set; }
        }

    }

}

Json.NET

ダウンロード
ドキュメント

ダウンロードしたファイルを解凍するとバイナリがフォルダ毎に別れています。プロジェクトの中にフォルダを作成して、その中へ既存のファイルとして呼び込んでから、そのパスで参照します。
-Net45:
  .NET latest (4.5)

-Net40:
  .NET 4.0

-Net35:
  .NET 3.5

-Net20:
  .NET 2.0

-WinRT:
  Windows 8 Store

-Portable45:
  .NET 4.5, Windows Phone 8, Windows 8 Store

-Portable40:
  .NET 4.0, Windows Phone 7, Windows 8 Store, Silverlight 4
関連する記事 JSONLint サービスを使って、JSON が正しいかどうかをチェックして整形する。
タグ:JSON
posted by lightbox at 2014-09-18 21:47 | VS(C#) | このブログの読者になる | 更新情報をチェックする

2014年07月25日


VS2010(C#) : HttpWebRequest クラスを使用して WEBアプリにバイナリデータを POST する

C# のコンソールアプリケーションで一般的に WEB アクセスする為に、HttpWebRequest クラスを使用します。

非同期ですと、いくぶん面倒ですが同期処理だと単純です。ここを参考に PowerShell でも利用できると思います。

▼ 以下関連する近い処理
VS2010(C#) : COMの Msxml2.ServerXMLHTTP を使用して WEBアプリにバイナリデータを POST する

C# ソースコード
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;

namespace PngUpload2 {
	class Program {
		static void Main(string[] args) {

			HttpWebRequest myReq =
			(HttpWebRequest)WebRequest.Create("http://yourdomain/put/put.php");

			// ****************************
			// ファイルを読み込む為のオブジェクト
			// ****************************
			FileStream fs = new FileStream(
				@"C:\user\web\web\various\put\winofsql.png",
				FileMode.Open, FileAccess.Read);

			// ****************************
			// ファイルを読み込むバイト型配列
			// ****************************
			byte[] bs = new byte[fs.Length];
			// ファイルの内容をすべて読み込む
			fs.Read(bs, 0, bs.Length);
			// 閉じる
			fs.Close();

			myReq.Method = "POST";
			//POST送信するデータの長さを指定
			myReq.ContentLength = bs.Length;

			// ****************************
			// データを書き込む
			// ****************************
			Stream reqStream = myReq.GetRequestStream();
			reqStream.Write(bs, 0, bs.Length);
			reqStream.Close();

			// ****************************
			// 結果を取得
			// ****************************
			WebResponse myRes = myReq.GetResponse();
			Stream resStream = myRes.GetResponseStream();
			StreamReader sr = new StreamReader(resStream, Encoding.UTF8);
			Console.WriteLine(sr.ReadToEnd());
			sr.Close();

			Console.ReadLine();

		}
	}
}

PHP 側については、『VBscript(または JScript) で簡単にバイナリファイルをアップロードする』 を参照して下さい。


関連する記事


タグ:C# framework HTTP
posted by lightbox at 2014-07-25 18:15 | VS(C#) | このブログの読者になる | 更新情報をチェックする

2014年07月24日


VS2010(C#) : COMの Msxml2.ServerXMLHTTP を使用して WEBアプリにバイナリデータを POST する

VB.net(2010) : COMの Msxml2.ServerXMLHTTP を使用して WEBアプリにバイナリデータを POST する
VBscript(または JScript) で簡単にバイナリファイルをアップロードする

いずれも同じ処理です。C# では、VB.net に比べていくぶん表現が厳密になっているのが解ります。文字列に使われている @ は、逐語的リテラル文字列と呼ばれており、使いやすさと読みやすさを考慮しています。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MSXML2;
using System.IO;

namespace PngUpload {
	class Program {
		static void Main(string[] args) {

			// ****************************
			// http 通信用のオブジェクトを作成
			// ****************************
			ServerXMLHTTP60 ServerXML = new ServerXMLHTTP60();

			// ****************************
			// 呼び出す URL を設定
			// ****************************
			String URL  = "http://yourdomain/put/put.php";

			// ****************************
			// POST する為に開く
			// ****************************
			ServerXML.open("POST", URL, false);

			// ****************************
			// タイムアウトの設定
			// ****************************
			int lResolve = 60 * 1000;
			int lConnect = 60 * 1000;
			int lSend = 60 * 1000;
			int lReceive = 60 * 1000;
			ServerXML.setTimeouts(lResolve, lConnect, lSend, lReceive);

			// ****************************
			// ファイルを読み込む為のオブジェクト
			// ****************************
			FileStream fs = new FileStream( 
				@"C:\user\web\web\put\winofsql.png", 
				FileMode.Open, FileAccess.Read);

			// ****************************
			// ファイルを読み込むバイト型配列
			// ****************************
			byte[] bs = new byte[fs.Length];
			// ファイルの内容をすべて読み込む
			fs.Read(bs, 0, bs.Length);
			// 閉じる
			fs.Close();

			// ****************************
			// 送信するデータの長さをヘッダにセット
			// ****************************
			ServerXML.setRequestHeader("Content-Length", bs.Length.ToString());
			// 送信
			ServerXML.send(bs);

			// ****************************
			// 結果の表示
			// ****************************
			Console.WriteLine(ServerXML.responseText);

			Console.ReadLine();

		}
	}
}



関連する記事


タグ:C# com
posted by lightbox at 2014-07-24 21:39 | VS(C#) | このブログの読者になる | 更新情報をチェックする

2014年04月10日


VS2010(C#) : System.Data.Odbc データ取得(SELECT)処理( MySQL )

OneDrive へ移動


スタンダードな C# から ODBC を使用した読み取り処理のテンプレートです。元は VB.net だったものを、Convert VB.NET to C# で変換して作成しています。

※ MySQL ODBC 5.2w Driver は、古いので、MySQL ODBC 5.3 Unicode Driver を使用して下さい( 93行 )
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Odbc;

namespace MySQL1 {
	class Program {
		static void Main(string[] args) {

			// 新しい OdbcConnection オブジェクトを作成
			OdbcConnection myCon = CreateConnection();

			if (myCon == null) {
				Console.WriteLine("処理が異常終了しました");
				return;
			}

			//---------------------------------------------------

			// レコードセットを取得する為の SQL を準備
			string myQuery = "SELECT `社員マスタ`.*,DATE_FORMAT(`生年月日`,'%Y-%m-%d') as `誕生日`" + " from `社員マスタ`";

			// SELECT 実行用のオブジェクトを作成
			OdbcCommand myCommand = new OdbcCommand();
			// 実行する為に必要な情報をセット
			myCommand.CommandText = myQuery;
			myCommand.Connection = myCon;

			// 実行後にレコードセットを取得する為のオブジェクトを作成
			OdbcDataReader myReader;
			// ここで SELECT を実行してその結果をオブジェクトに格納する
			myReader = myCommand.ExecuteReader();

			// 読み出し
			// Rewad メソッドは、行が存在する場合は true、それ以外の場合は false を返します

			while (myReader.Read()) {
				// 文字列
				Console.Write(GetValue(myReader, "社員コード") + " : ");
				Console.Write(GetValue(myReader, "氏名") + " : ");

				// 整数
				Console.Write(GetValue(myReader, "給与") + " : ");

				// 日付
				Console.Write(GetValue(myReader, "作成日") + " : ");
				Console.Write(GetValue(myReader, "更新日") + " : ");
				Console.Write(GetValue(myReader, "生年月日") + " : ");
				Console.Write(GetValue(myReader, "誕生日"));

				Console.WriteLine();

			}

			myReader.Close();
			//---------------------------------------------------

			EndConnection(myCon);

		}

		// ******************************************************
		// 接続終了
		// ******************************************************

		static void EndConnection(OdbcConnection myCon) {
			// 接続を閉じる
			myCon.Close();

			// OdbcConnection オブジェクトに使用されているすべてのリソースを解放
			myCon.Dispose();

			// 処理終了
			Console.WriteLine("処理が終了しました");

			// 一時停止
			Console.Write("Enterキーを押して下さい : ");
			Console.ReadLine();

		}

		// ******************************************************
		// 接続作成
		// ******************************************************
		static OdbcConnection CreateConnection() {

			// 新しい OdbcConnectionStringBuilder オブジェクトを作成
			OdbcConnectionStringBuilder builder = new OdbcConnectionStringBuilder();

			// ドライバ文字列をセット ( 波型括弧{} は必要ありません ) 
			// 文字列を正確に取得するには、レジストリ : HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI
			builder.Driver = "MySQL ODBC 5.2w Driver";

			// 接続用のパラメータを追加
			builder.Add("SERVER", "localhost");
			builder.Add("DATABASE", "lightbox");
			builder.Add("UID", "root");
			builder.Add("PWD", "パスワード");

			// 内容を確認
			Console.WriteLine(builder.ConnectionString);

			// 新しい OdbcConnection オブジェクトを作成
			OdbcConnection myCon = new OdbcConnection();

			// 接続文字列を設定
			myCon.ConnectionString = builder.ConnectionString;

			// 接続を開く
			try {
				myCon.Open();
			}
			catch (OdbcException ex) {
				Console.WriteLine("接続エラーです");
				// Console.WriteLine( ex.Message )
				ErrorAction(ex);
				return null;
			}

			return myCon;

		}

		// ******************************************************
		// エラー処理
		// ******************************************************

		static void ErrorAction(OdbcException ex) {
			string CrLf = "\r\n";
			string errorMessages = "";
			int i = 0;

			for (i = 0; i <= ex.Errors.Count - 1; i++) {
				errorMessages += "Index #" + i.ToString() + CrLf + "Message: " + ex.Errors[i].Message + CrLf + "NativeError: " + ex.Errors[i].NativeError.ToString() + CrLf + "Source: " + ex.Errors[i].Source + CrLf + "SQL: " + ex.Errors[i].SQLState + CrLf;
			}

			Console.WriteLine(errorMessages);

		}


		// ********************************************************
		// 列データ取得
		//
		// 列データを文字列として取得しますが、NULL の場合は
		// 空文字列を返します
		// ********************************************************
		static string GetValue(OdbcDataReader myReader, string strName) {

			string ret = "";
			int fld = 0;

			// 指定された列名より、テーブル内での定義順序番号を取得
			fld = myReader.GetOrdinal(strName);
			// 定義順序番号より、NULL かどうかをチェック
			if (myReader.IsDBNull(fld)) {
				ret = "";
			}
			else {
				// NULL でなければ内容をオブジェクトとして取りだして文字列化する
				ret = myReader.GetValue(fld).ToString();
			}

			// 列の値を返す
			return ret;

		}

	}
}


以下は、show create table で取得した MySQL用の テーブル作成用 SQL です。
CREATE TABLE `社員マスタ` (
  `社員コード` varchar(4) NOT NULL DEFAULT '',
  `氏名` varchar(50) DEFAULT NULL,
  `フリガナ` varchar(50) DEFAULT NULL,
  `所属` varchar(4) DEFAULT NULL,
  `性別` int(11) DEFAULT NULL,
  `作成日` datetime DEFAULT NULL,
  `更新日` datetime DEFAULT NULL,
  `給与` int(11) DEFAULT NULL,
  `手当` int(11) DEFAULT NULL,
  `管理者` varchar(4) DEFAULT NULL,
  `生年月日` datetime DEFAULT NULL,
  PRIMARY KEY (`社員コード`)
)




posted by lightbox at 2014-04-10 19:47 | VS(C#) | このブログの読者になる | 更新情報をチェックする

2013年11月04日


VS2010 WPF(C#) DataGrid + データベース バインド / DataGrid に MDB のデータを読み込んで表示するテンプレート

SkyDrive へ移動




解説ページ

DataGrid へデータベースの内容を表示する問い合わせのサンプルですが、XAML を利用する上でデータはバインドでコントロールに表示されます。その為、データベースのデータを扱う為のプライベートクラス( SELECT 文の列リストを格納するクラス )を作成して利用します。

DataGrid は、ある手順を踏むと、そのクラスから自動的に列を作成してくれる上に、バインドの Mode=OneWay のルールで、コレクションの内容を変更するだけでコントロールの表示を変更する事ができます。


posted by lightbox at 2013-11-04 17:36 | VS(C#) | このブログの読者になる | 更新情報をチェックする

2013年11月01日


VS2012 WPF(C#) : 『TKMP.DLL を使用したイベントによる非同期メール受信処理を Task(await) を使用して順次処理のように記述する』テンプレート

SkyDrive へ移動


Framework 4.5 では、Task<TResult> クラスによって非同期処理の結果を取得してあたかも同期処理のような記述を行う事ができるようになりましたが、既存の非同期処理をそのように書き換える為に、TaskCompletionSource<TResult> クラスを使用します。

単純に考えると、Task を戻り値とするメソッド内は全て管理されていて、その中で登録されたイベントは全て管理下に置かれるようです。イベントが終了するまで、メソッドが終わる事無く、TaskCompletionSource<TResult> クラスの TrySetResult( SetResult との違いは良く解りません )で、値をセットした時にメソッドが終了するように見えます。

こうする事によって、大きなメリットの一つとして、UI スレッドにふつうに戻って来て処理を行えるところであり、当然ループ内の一部として自然に行を追加しながら非同期を実現する事ができました



MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Net;
using System.Windows;
using System.Windows.Input;
using System.Collections.ObjectModel;
using TKMP.Net;
using System.IO;
using TKMP.Reader;
using System.Threading;
using System.Threading.Tasks;

namespace WPF_DataGrid_MailGet1 {
	public partial class MainWindow : Window {

		private MainViewModel mvm = new MainViewModel();
		private ImapClient client = null;

		// *********************************************
		// コンストラクタ
		// *********************************************
		public MainWindow() {
			InitializeComponent();

			this.dataGrid1.DataContext = mvm;
		}

		// 接続および、メールヘッダの取得
		private async void actButton_Click(object sender, RoutedEventArgs e) {

			mvm.mail_data.Clear();

			BasicImapLogon logon = new BasicImapLogon(this.userName.Text, this.password.Password);
			client = new ImapClient(logon, "imap.gmail.com", 993);
			client.AuthenticationProtocol = AuthenticationProtocols.SSL;

			if (!client.Connect()) {
				return;
			}

			// メールデータ一覧を格納するオブジェクト
			IMailData[] md = client.GetMailList();

			// データがありません
			if (md == null) {
				return;
			}

			// メールデータの数
			mailCount.Text = md.Length.ToString();

			// 読込み制限
			int maxCount = 20;
			int idx = 0;

			// 非同期で全て表示
			foreach (var data in md) {

				idx++;
				if (idx > maxCount) {
					break;
				}

				// Framework 4.5 : 値を返す非同期処理
				MailReader reader = await ReadBodyAnsync( data );

				// UI スレッドに戻って来ているので、特殊な処理は必要無い
				string from = "";
				string subject = "";
				string mdate = "";
				// ヘッダの一覧より、目的のヘッダを探す
				foreach (TKMP.Reader.Header.HeaderString headerdata in reader.HeaderCollection) {

					if (headerdata.Name == "From") {
						from = headerdata.Data;
					}
					if (headerdata.Name == "Subject") {
						subject = headerdata.Data;
					}
					if (headerdata.Name == "Date") {
						mdate = headerdata.Data;
					}

				}

				// 行追加
				mvm.mail_data.Add(new ItemViewModel() {
					from = from,
					subject = subject,
					mdate = mdate
				});

			}
			// ソース的には、順次処理なので全てのデータ処理後のクローズ
			client.Close();

		}

		// *********************************************
		// 戻り値を返す事のできる非同期処理 【開始】
		// *********************************************
		private TaskCompletionSource<MailReader> tcs = null;
		private Task<MailReader> ReadBodyAnsync(IMailData MailData) {

			// 戻り値用のクラス
			tcs = new TaskCompletionSource<MailReader>();

			// 個別にイベント登録
			MailData.BodyLoaded += new EventHandler(MailData_event);
			// 非同期処理開始
			MailData.ReadBodyAnsync();

			return tcs.Task;
		}

		// 本来のイベント処理
		private void MailData_event(object sender, EventArgs e) {

			IMailData MailData = (IMailData)sender;

			// イベント削除
			MailData.BodyLoaded -= new EventHandler(MailData_event);

			// 本文無し( 本文が必要な場合は、false で、reader.MainText )
			MailReader reader = new MailReader(MailData.DataStream, true);

			// ****************************
			// 戻り値用のクラスの戻り値をセット
			// ****************************
			tcs.TrySetResult(reader);

		}
		// *********************************************
		// 戻り値を返す事のできる非同期処理 【終了】
		// *********************************************


		// ダブルクリック
		private void dataGrid1_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
			Debug.WriteLine(dataGrid1.SelectedIndex);

		}


	}
}

参考ページ

c# - Best way to convert callback-based async method to awaitable task - Stack Overflow
c# - TaskCompletionSource : When to use SetResult() versus TrySetResult(), etc - Stack Overflow

関連するページ

▼ このページの処理の元となった、通常のイベント非同期処理
WPF(C#) : 『DataGrid に、TKMP.DLL を使用して非同期にメールヘッダを受信する』 テンプレート



posted by lightbox at 2013-11-01 20:29 | VS(C#) | このブログの読者になる | 更新情報をチェックする

2013年10月29日


Framework4(C#) : WebClient で Post と Get する汎用 static クラス

テストしたのは、Windows7 + Visual Studio 2010 + WPF アプリケーションです。

Web アクセスには、UrlEncode が必要になりますが、HttpUtility.UrlEncode はプロジェクトのプロパティで、『.NET Framework 4』にして System.Web を参照します。最初にプロジェクトを作成した場合、『.NET Framework 4 Client Profile』にセットされている場合があり、その場合  System.Web を参照できません。

HttpUtility.UrlEncode は、Windows Phone(OS 7.1) にもある事はあるのですが、エンコード結果が UTF-8 系列しか指定できないので、Encoding を指定する第二引数がありません。参照も、System.Windows の中の System.Net にあります。ですから、このクラスは Windows Phone(OS 7.1) では使用できません。

%エンコーディングの仕様が違いますが、WEB へ送信する場合は、Uri.EscapeDataString でも使用可能で、Twitter への投稿ではこちら(RFC 3986)が良いと思いますが、文字列は UTF-8 に変換されてエンコーディングされます。
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Web;

namespace winofsql {

	class Tool {

        public static string serverEncoding = "utf-8";

		// *********************************************
		// UTF-8 POST
		// *********************************************
		public static string Post(string url,
            Dictionary<string, string> param,
            UploadStringCompletedEventHandler UploadStringCompleted=null) {

			string result = "";

			try {
				WebClient webClient = new WebClient();
                webClient.Encoding = Encoding.GetEncoding(serverEncoding);

                if ( UploadStringCompleted != null ) {
                    // 呼び出し側でラムダ式を使う事を想定した
                    // イベント登録
                    webClient.UploadStringCompleted += UploadStringCompleted;
                }

                webClient.Headers["Content-Type"] = "application/x-www-form-urlencoded";

                string data_string = "";

                foreach (KeyValuePair<string, string> kvp in param)
                {
                    if (data_string != "")
                    {
                        data_string += "&";
                    }
                    data_string += kvp.Key + "=";

            		// *******************************************************
                    // プロジェクトのプロパティの対象フレームワークを 
                    //『Framework 4』 にして System.Web を参照します
            		// *******************************************************
                    data_string += HttpUtility.UrlEncode(kvp.Value, Encoding.UTF8);
                }
                
                webClient.UploadStringAsync(new Uri(url), "POST", data_string);

			}
			catch (Exception Err) {
				result = "ERROR: " + Err.Message;
			}

            return result;

		}

		// *********************************************
		// エンコード指定 POST
		// *********************************************
		public static string Post(string url,
            string encoding,
            Dictionary<string, string> param,
            UploadStringCompletedEventHandler UploadStringCompleted=null) {

			string result = "";

			try {
				WebClient webClient = new WebClient();
                webClient.Encoding = Encoding.GetEncoding(serverEncoding);

                if ( UploadStringCompleted != null ) {
                    // 呼び出し側でラムダ式を使う事を想定した
                    // イベント登録
                    webClient.UploadStringCompleted += UploadStringCompleted;
                }

                webClient.Headers["Content-Type"] = "application/x-www-form-urlencoded";

                string data_string = "";

                foreach (KeyValuePair<string, string> kvp in param)
                {
                    if (data_string != "")
                    {
                        data_string += "&";
                    }
                    data_string += kvp.Key + "=";

            		// *******************************************************
                    // プロジェクトのプロパティの対象のフレームワークを 
                    //『.NET Framework 4』 にして System.Web を参照します
            		// *******************************************************
                    data_string += HttpUtility.UrlEncode(kvp.Value, Encoding.GetEncoding(encoding));
                }
                
                webClient.UploadStringAsync(new Uri(url), "POST", data_string);

			}
			catch (Exception Err) {
				result = "ERROR: " + Err.Message;
			}

            return result;

		}

		// *********************************************
		// URL のみ呼び出し GET
		// *********************************************
		public static string Get(
            string url,
            DownloadStringCompletedEventHandler DownloadStringCompleted=null) {

			string result = "";

			try {
				WebClient webClient = new WebClient();
                webClient.Encoding = Encoding.GetEncoding(serverEncoding);

                if ( DownloadStringCompleted != null ) {
                    // 呼び出し側でラムダ式を使う事を想定した
                    // イベント登録
                    webClient.DownloadStringCompleted += DownloadStringCompleted;
                }

                webClient.DownloadStringAsync(new Uri(url));

			}
			catch (Exception Err) {
				result = "ERROR: " + Err.Message;
			}

            return result;

		}

		// *********************************************
		// データ呼び出し( UTF-8 ) GET
		// *********************************************
		public static string Get(
            string url, 
            Dictionary<string, string> param,
            DownloadStringCompletedEventHandler DownloadStringCompleted=null) {

            string result = "";

            try
            {
                WebClient webClient = new WebClient();
                webClient.Encoding = Encoding.GetEncoding(serverEncoding);

                if (DownloadStringCompleted != null)
                {
                    // 呼び出し側でラムダ式を使う事を想定した
                    // イベント登録
                    webClient.DownloadStringCompleted += DownloadStringCompleted;
                }

                string data_string = "";

                foreach (KeyValuePair<string, string> kvp in param)
                {
                    if (data_string != "")
                    {
                        data_string += "&";
                    }
                    data_string += kvp.Key + "=";

                    // *******************************************************
                    // プロジェクトのプロパティの対象フレームワークを 
                    //『Framework 4』 にして System.Web を参照します
                    // *******************************************************
                    data_string += HttpUtility.UrlEncode(kvp.Value, Encoding.UTF8);
                }

                webClient.DownloadStringAsync(new Uri(url + "?" + data_string));

            }
            catch (Exception Err)
            {
                result = "ERROR: " + Err.Message;
            }

            return result;

		}

		// *********************************************
		// データ呼び出し( エンコード指定 ) GET
		// *********************************************
		public static string Get(
            string url,
            string encoding,
            Dictionary<string, string> param,
            DownloadStringCompletedEventHandler DownloadStringCompleted=null) {

            string result = "";

            try
            {
                WebClient webClient = new WebClient();
                webClient.Encoding = Encoding.GetEncoding(serverEncoding);

                if (DownloadStringCompleted != null)
                {
                    // 呼び出し側でラムダ式を使う事を想定した
                    // イベント登録
                    webClient.DownloadStringCompleted += DownloadStringCompleted;
                }

                string data_string = "";

                foreach (KeyValuePair<string, string> kvp in param)
                {
                    if (data_string != "")
                    {
                        data_string += "&";
                    }
                    data_string += kvp.Key + "=";

                    // *******************************************************
                    // プロジェクトのプロパティの対象フレームワークを 
                    //『Framework 4』 にして System.Web を参照します
                    // *******************************************************
                    data_string += HttpUtility.UrlEncode(kvp.Value, Encoding.GetEncoding(encoding));
                }

                webClient.DownloadStringAsync(new Uri(url + "?" + data_string));

            }
            catch (Exception Err)
            {
                result = "ERROR: " + Err.Message;
            }

            return result;

		}

	}
}


使用方法のサンプル
Tool.serverEncoding = "utf-8";
Tool.Post("http://student.xii.jp/lightbox/php_sample_1/log.php",
	"utf-8",
	new Dictionary<string, string>() { { "send", "ok" }, { "text", "日本語" } },
(object _sender, UploadStringCompletedEventArgs _e) =>
{
	// Error プロパティがセットされているとエラー
	if (_e.Error != null)
	{
		// エラー処理
	}
	// 正常な結果
	else
	{
		// 正常処理
	}
});

関連する記事

Framework4.5(C#)ストア : HttpClient で Post と Get する汎用 static クラス
Framework4(C#) : Windows Phone OS 7.1 : WebClient で Post と Get する汎用 static クラス
Android で Post と Get

いろいろな言語におけるバーセントエンコーディング





posted by lightbox at 2013-10-29 21:01 | VS(C#) | このブログの読者になる | 更新情報をチェックする

2013年10月27日


WPF(C#) : 『DataGrid に、TKMP.DLL を使用して非同期にメールヘッダを受信する』 テンプレート

SkyDrive へ移動


メールサーバーは GMail の IMAP を使用してテストしています



MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Net;
using System.Windows;
using System.Windows.Input;
using System.Collections.ObjectModel;
using TKMP.Net;
using System.IO;
using TKMP.Reader;
using System.Threading;

namespace WPF_DataGrid1 {
	public partial class MainWindow : Window {

		private MainViewModel mvm = new MainViewModel();
		private SynchronizationContext sc = null;
		private ImapClient client = null;
		private int endCounter = 0;

		// *********************************************
		// コンストラクタ
		// *********************************************
		public MainWindow() {
			InitializeComponent();

			this.dataGrid1.DataContext = mvm;
		}

		// 接続および、メールヘッダの取得
		private void actButton_Click(object sender, RoutedEventArgs e) {

			mvm.mail_data.Clear();

			BasicImapLogon logon = new BasicImapLogon(this.userName.Text, this.password.Password );
			client = new ImapClient(logon, "imap.gmail.com", 993);
			client.AuthenticationProtocol = AuthenticationProtocols.SSL;

			if (!client.Connect()) {
				return;
			}

			// メールデータ一覧を格納するオブジェクト
			IMailData[] md = client.GetMailList();

			// データがありません
			if (md == null) {
				return;
			}

			// メールデータの数
			mailCount.Text = md.Length.ToString();

			// 読込み制限
			int maxCount = 20;
			int idx = 0;

			// 接続解除用
			endCounter = 0;

			// 非同期で全て表示
			foreach( var data in md ) {

				idx++;
				if (idx > maxCount) {
					break;
				}

				// 個別にイベント登録
				data.BodyLoaded += new EventHandler(MailData_BodyLoaded);
				// 非同期処理開始
				data.ReadBodyAnsync();

			}

		}

		private void MailData_BodyLoaded(object sender, EventArgs e) {

			IMailData MailData = (IMailData)sender;

			// 本文無し( 本文が必要な場合は、false で、reader.MainText )
			MailReader reader = new MailReader(MailData.DataStream, true);

			//Console.WriteLine(reader.MainText);

			// UI スレッドへの処理( この場合、post_state は null )
			sc.Post((object post_state) => {

				string from = "";
				string subject = "";
				string mdate = "";
				// ヘッダの一覧より、目的のヘッダを探す
				foreach (TKMP.Reader.Header.HeaderString headerdata in reader.HeaderCollection) {

					if (headerdata.Name == "From") {
						from = headerdata.Data;
					}
					if (headerdata.Name == "Subject") {
						subject = headerdata.Data;
					}
					if (headerdata.Name == "Date") {
						mdate = headerdata.Data;
					}

				}

				// 行追加
				mvm.mail_data.Add(new ItemViewModel() {
					from = from,
					subject = subject,
					mdate = mdate
				});

			}, null);

			// イベント削除
			MailData.BodyLoaded -= new EventHandler(MailData_BodyLoaded);

			// 接続解除用
			endCounter++;
			if (endCounter == 20) {
				client.Close();
			}
		}

		// UI スレッドへの処理用
		private void Window_Loaded(object sender, RoutedEventArgs e) {
			sc = SynchronizationContext.Current;
		}

		// ダブルクリック
		private void dataGrid1_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
			Debug.WriteLine(dataGrid1.SelectedIndex);

		}


	}
}

非同期でのサーバーとの通信処理はすべてキューとして扱われるため、 前の処理が終了する前に次の要求を発行すると、要求順に順次処理が行われます
関連する記事 WPF(C#) : 『DataGrid に、バインド用クラスを使って自動的にカラムと行を生成する』 テンプレート
posted by lightbox at 2013-10-27 23:08 | VS(C#) | このブログの読者になる | 更新情報をチェックする

WPF(C#) : 『DataGrid に、バインド用クラスを使って自動的にカラムと行を生成する』 テンプレート

SkyDrive へ移動



※ Window の背景にイラスト画像を使用しています

DataGrid の重要なプロパティ
ItemsSource="{Binding mail_data}"
AutoGenerateColumns="True"
CanUserAddRows="false"
MainWindow.xaml
<Window x:Class="WPF_MailGet.MainWindow"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	mc:Ignorable="d"
	Title="MainWindow"
	Height="719"
	Width="805"
	BorderBrush="Black"
	BorderThickness="1">
	<Window.Background>
		<ImageBrush
			ImageSource="/WPF_MailGet;component/Images/back_001.jpg"
			Stretch="UniformToFill"
			TileMode="None" />
	</Window.Background>
	<!-- このウインドウのリソース -->
	<Window.Resources>

		<Style
			TargetType="{x:Type ListView}">
			<Setter
				Property="ItemContainerStyle">
				<Setter.Value>
					<Style
						TargetType="ListViewItem">
						<Setter
							Property="VerticalContentAlignment"
							Value="Top" />
					</Style>
				</Setter.Value>
			</Setter>
		</Style>
		
		<!-- 一覧データ 用の表示部品定義 -->
		<DataTemplate
			x:Key="ListFromTemplate">

			<StackPanel
				HorizontalAlignment="Left"
				Width="60">
				<TextBlock
					Text="{Binding from}"
					TextWrapping="Wrap"
					Padding="4" />
			</StackPanel>

		</DataTemplate>
		
		<DataTemplate
			x:Key="ListSubjectTemplate">
			
			<StackPanel
				Margin="0,0,0,17"
				Width="250">
				<Border
					BorderThickness="1"
					BorderBrush="Black"
					Padding="4"
					Height="50">
				<TextBlock
					Text="{Binding subject}"
					TextWrapping="Wrap" />
				</Border>
			</StackPanel>

		</DataTemplate>
	</Window.Resources>
	
	<Grid
		AllowDrop="True">
		<Grid.RowDefinitions>
			<RowDefinition
				Height="70*" />
			<RowDefinition
				Height="608*" />
		</Grid.RowDefinitions>
		
		<!--実行ボタン-->
		<Button
			Name="actButton"
			Content="データ表示"
			Height="35"
			HorizontalAlignment="Left"
			Margin="40,26,0,0"
			VerticalAlignment="Top"
			Width="154"
			Click="actButton_Click" />

		<!--一覧表示-->
		<DataGrid
			Grid.Row="1"
			Height="534"
			HorizontalAlignment="Left"
			Margin="40,0,0,0"
			Name="dataGrid1"
			VerticalAlignment="Top"
			Width="700"
			Background="#C5FFFFFF"
			MouseDoubleClick="dataGrid1_MouseDoubleClick"
			ItemsSource="{Binding mail_data}"
			AutoGenerateColumns="True"
			CanUserAddRows="false"
			IsReadOnly="True">
			<!--<DataGrid.Columns>
				<DataGridTemplateColumn
					Header="差出人"
					CellTemplate="{StaticResource ListFromTemplate}">
				</DataGridTemplateColumn>
				<DataGridTemplateColumn
					Header="件名"
					CellTemplate="{StaticResource ListSubjectTemplate}">
				</DataGridTemplateColumn>
			</DataGrid.Columns>-->
		</DataGrid>
		
	</Grid>
</Window>

コメント部分は、カラムをテンプレートで作成してカスタマイズする場合に使用します。

MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Net;
using System.Windows;
using System.Windows.Input;
using System.Collections.ObjectModel;

namespace WPF_MailGet {
	public partial class MainWindow : Window {

		private MainViewModel mvm = new MainViewModel();
		// *********************************************
		// コンストラクタ
		// *********************************************
		public MainWindow() {
			InitializeComponent();

			this.dataGrid1.DataContext = mvm;
		}

		private void actButton_Click(object sender, RoutedEventArgs e) {

			mvm.mail_data.Add(new ItemViewModel() {
				from = "Button@event.DataGrid.wpf",
				subject = "DataGrid は自動カラム作成が有効です",
				mdate = "2013/10/26 19:00:30",
			});
		}

		private void dataGrid1_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
			Debug.WriteLine(dataGrid1.SelectedIndex);

			mvm.mail_data.Add(new ItemViewModel() {
				from = "DoubleClick@event.DataGrid.wpf",
				subject = "CanUserAddRowsは、\n意図的に false にする必要があります",
				mdate = "2013/10/26 19:00:30",
			});

			mvm.mail_data[0].mdate = "0000/00/00";

		}

	}
}


MainViewModel.cs
using System;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace WPF_MailGet {

	// *********************************************
	// バインドする一覧データのを定義するクラス
	// *********************************************
	public class MainViewModel : MainBaseModel {
		// *****************************************************
		// コンストラクタ
		// *****************************************************
		public MainViewModel() {
			mail_data = new ObservableCollection<ItemViewModel>();
		}

		// *****************************************************
		// バインド用のコレクションのプロパティ
		// *****************************************************
		public ObservableCollection<ItemViewModel> mail_data { get; set; }

	}
}

ItemViewModel.cs
using System;
using System.ComponentModel;

namespace WPF_MailGet {
	// *********************************************
	// バインドする一覧データの構造を定義するクラス
	// *********************************************
	public class ItemViewModel : ItemBaseModel {

		// *********************************************
		// from エントリ
		// *********************************************
		private string _from;
		public string from {
			get { return _from; }
			set {
				SetAndNotifyString(GetName(() => from), ref _from, value);
			}
		}

		// *********************************************
		// subject エントリ
		// *********************************************
		private string _subject;
		public string subject {
			get { return _subject; }
			set {
				SetAndNotifyString(GetName(() => subject), ref _subject, value);
			}
		}

		// *********************************************
		// mdate エントリ
		// *********************************************
		private string _mdate;
		public string mdate {
			get { return _mdate; }
			set {
				SetAndNotifyString(GetName(() => mdate), ref _mdate, value);
			}
		}

	}
}



posted by lightbox at 2013-10-27 00:47 | VS(C#) | このブログの読者になる | 更新情報をチェックする

2013年10月18日


VS2010(C#) : データベースを System.Data.Linq.DataContext で読み込んでからの LINQ

標準クエリ演算子の概要
標準クエリ演算子は、統合言語クエリ (LINQ) パターンを形成するメソッドです。 ほとんどの場合、そのメソッドの操作の対象はシーケンスです。シーケンスとは、IEnumerable インターフェイスまたは IQueryable インターフェイスを実装している型を持つオブジェクトのことです。 標準クエリ演算子には、クエリ機能が用意されています。たとえば、フィルター処理、射影、集計、並べ替えなどです。
データベースへのアクセスは SQL で実行しておいて、メモリにあるデータに対して LINQ を使用します。文字列の比較の為に、メソッドを一つ追加しています。 変数名に日本語を使用しているのは、テーブルの列定義が日本語の為です。変数を 英数字にするには、SELECT 構文で列に別名を付けて、格納用のクラスをその名前にします。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data.Odbc;
using System.Data.Linq;
using System.Data;

namespace DataContextTest {

	class Program {
		static void Main(string[] args) {

			OdbcConnection cn = null;
			string cs = "Driver={MySQL ODBC 5.2w Driver};" +
						"Server=localhost;" +
						"Database=lightbox;" +
						"Uid=root;" +
						"Pwd=password;";
			try {
				cn = new OdbcConnection(cs);
				// System.Data.Linq を参照
				DataContext context = new DataContext(cn);

				// select * from 社員マスタ で動作します
				string query = String.Format("select 社員コード,氏名 from 社員マスタ");

				// シーケンスとは、IEnumerable<T> インターフェイスまたは
				// IQueryable<T> インターフェイスを実装している型を持つオブジェクト
				IEnumerable<Syain> tables = context.ExecuteQuery<Syain>(query);

				var q =
				  from s in tables
				  where comp(true,s.社員コード,"0005")
				  select s;

				foreach (var s in q) {
					Console.Write("{0}, {1}\n", s.社員コード, s.氏名);
				}

			}
			catch (Exception ex) {
				Console.WriteLine(ex.Message);
			}

			if (cn.State == ConnectionState.Open) {
				cn.Close();
				cn.Dispose();
			}

			Console.ReadLine();
		}

		// 文字列比較用
		public static bool comp(bool type,string a, string b) {

			if (a == b) {
				return true;
			}

			if (a.CompareTo(b) < 0) {
				return !type;
			}
			else {
				return type;
			}
		}

		private class Syain {
			public string @社員コード { get; set; }
			public string @氏名 { get; set; }
		}
	}
}




posted by lightbox at 2013-10-18 22:42 | VS(C#) | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します


Windows
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

Android SDK ポケットリファレンス
改訂版 Webデザイナーのための jQuery入門
今すぐ使えるかんたん ホームページ HTML&CSS入門
CSS ドロップシャドウの参考デモ
Google Hosted Libraries
cdnjs
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり