SQLの窓

2013年10月29日


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

Windows Phone では、Encoding に UTF-8 系しか無いので、アクセス先は UTF-8 限定となります。

  • utf-8 : UTF8Encoding
  • utf-16 : UnicodeEncoding (リトル エンディアン)
  • utf-16BE : UnicodeEncoding (ビッグ エンディアン)
  • utf-16LE :
  • using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Text;
    
    namespace winofsql {
    
    	class Tool {
    
    		// *********************************************
    		// UTF-8 POST
    		// *********************************************
    		public static string Post(string url,
                Dictionary<string, string> param,
                UploadStringCompletedEventHandler UploadStringCompleted=null) {
    
    			string result = "";
    
    			try {
    				WebClient webClient = new WebClient();
    
                    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 + "=";
    
                		// *******************************************************
                        // System.Windows 内の System.Web にあります
                		// *******************************************************
                        data_string += HttpUtility.UrlEncode(kvp.Value);
                    }
                    
                    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();
    
                    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();
    
                    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 + "=";
    
                        // *******************************************************
                        // System.Windows 内の System.Web にあります
                        // *******************************************************
                        data_string += HttpUtility.UrlEncode(kvp.Value);
                    }
    
                    webClient.DownloadStringAsync(new Uri(url + "?" + data_string));
    
                }
                catch (Exception Err)
                {
                    result = "ERROR: " + Err.Message;
                }
    
                return result;
    
    		}
    
    	}
    }
    
    
    関連する記事
    
    いろいろな言語におけるバーセントエンコーディング
    
    Framework4.5(C#)ストア : HttpClient で Post と Get する汎用 static クラス
    Framework4(C#) : WebClient で Post と Get する汎用 static クラス
    Android で Post と Get
    
    
    
    
    posted by lightbox at 2013-10-29 21:00 | Windows Phone | このブログの読者になる | 更新情報をチェックする

    2013年10月11日


    VS2010(C#)Phone : ListBox Twitter 検索テンプレート

    SkyDrive へ移動
    
    
    Windows Phone のコードの需要があるかどうかは疑問ですが、Microsoft が用意したバインドのテンプレートは、Windows Phone にしか無いようです。
    
    
    Twitter_Search.cs
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Diagnostics;
    using System.Security.Cryptography;
    
    namespace VS2010_Twitter
    {
        class Twitter_Search
        {
            private string _consumer_key;
            private string _consumer_secret;
            private string _token;
            private string _secret;
    
            private string _tweet_api = "https://api.twitter.com/1.1/search/tweets.json";
    
            public Twitter_Search(
                string consumer_key,
                string consumer_secret,
                string token,
                string secret
                )
            {
                _consumer_key = consumer_key;
                _consumer_secret = consumer_secret;
                _token = token;
                _secret = secret;
            }
    
            public void Tweet(string text, int count, DownloadStringCompletedEventHandler newEvent = null)
            {
    
                WebClient wc = new WebClient();
    
                if (newEvent != null)
                {
                    wc.DownloadStringCompleted += newEvent;
                }
    
                // ソートされるリスト
                Dictionary<string, string> sl = new Dictionary<string, string>();
                sl.Add("count", count.ToString());
                sl.Add("oauth_consumer_key", _consumer_key);
                sl.Add("oauth_nonce", Nonce());
                sl.Add("oauth_signature_method", "HMAC-SHA1");
                sl.Add("oauth_timestamp", TimeStamp());
                sl.Add("oauth_token", _token);
                sl.Add("oauth_version", "1.0");
                sl.Add("q", rfc3986(Uri.EscapeDataString(text)));
    
                // http ヘッダ用シグネチャ作成
                string work = "";
                foreach (KeyValuePair<string, string> kvp in sl)
                {
                    if (work != "")
                    {
                        work += "&";
                    }
                    work += kvp.Key + "=" + kvp.Value;
                }
    
                string work2 = "";
                // メソッド
                work2 += "GET" + "&";
                // API URL
                work2 += rfc3986(Uri.EscapeDataString(_tweet_api)) + "&";
                // Oauth + データ
                work2 += rfc3986(Uri.EscapeDataString(work));
    
                // OAuth tool チェック用
                Debug.WriteLine(work2);
    
                string oauth_signature = Signature(work2);
    
                // ヘッダ情報を作成
                work = "";
                foreach (KeyValuePair<string, string> kvp in sl)
                {
                    // oauth_* のみを使用する
                    if (work != "")
                    {
                        if ((kvp.Key + "      ").Substring(0, 6) == "oauth_")
                        {
                            work += ", ";
                        }
                    }
                    if ((kvp.Key + "      ").Substring(0, 6) == "oauth_")
                    {
                        work += kvp.Key + "=" + Dd(kvp.Value);
                    }
                }
                // シグネチャを追加( ヘッダーはソートの必要は無い )
                work += ", oauth_signature=" + Dd(rfc3986(Uri.EscapeDataString(oauth_signature)));
    
                // OAuth tool チェック用
                Debug.WriteLine(work);
    
                // フォーマットは、 OAuth tool で確認。
                wc.Headers["Authorization"] = "OAuth " + work;
    
                // 投稿
                wc.DownloadStringAsync(new Uri(
                    _tweet_api +
                    "?" +
                    "q=" + sl["q"] +
                    "&count=" + sl["count"]
                ));
    
            }
    
            private string rfc3986(string base_string)
            {
                string result = base_string.Replace("!", "%21");
                result = result.Replace("'", "%27");
                result = result.Replace("(", "%28");
                result = result.Replace(")", "%29");
                result = result.Replace("*", "%2A");
                return result;
            }
    
            // ダブルクォートで挟む
            private string Dd(string base_string)
            {
                return "\"" + base_string + "\"";
            }
    
            private string Nonce()
            {
                Random rand = new Random();
                int nonce = rand.Next(1000000000);
                return nonce.ToString();
            }
    
            // タイムスタンプ
            private string TimeStamp()
            {
                TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                return Convert.ToInt64(ts.TotalSeconds).ToString();
            }
    
            // シグネチャ
            private string Signature(string target)
            {
                string work = _consumer_secret + "&" + _secret;
                byte[] bin = Encoding.UTF8.GetBytes(target);
    
                HMACSHA1 hmacsha1 = new HMACSHA1();
                hmacsha1.Key = Encoding.UTF8.GetBytes(work);
                byte[] hash = hmacsha1.ComputeHash(bin);
    
                return Convert.ToBase64String(hash);
            }
        }
    }
    
    
    関連する記事
    
    VS2012(C#)ストア : ListView Twitter 検索テンプレート
    
    
    
    
    posted by lightbox at 2013-10-11 20:38 | Windows Phone | このブログの読者になる | 更新情報をチェックする

    2013年07月12日


    Live SDK v5.4 : VS2010 + Windows Phone / 画像アップロード

    VS2010 で動いたのは、Windows Phone だけでした。Form アプリで動作させるには、VS2012 が必要なようです。( VS2010 で、一部、情報の参照は動いたのですが、アップロードやダウンロードという一番必要なものが落ちました。dll が足らないとか言われます。しかし、VS2012 では同じものが動作しています )
    
    Microsoft のドキュメントは、どれもこれも微妙にウソでした。
    
    my:SignInButton の追加は、コントロールの Toolbox の『Windows Phone コントロール』で右クリックして『アイテムの選択』で、Program Files 内の "Microsoft SDKs\Live\v5.4\Windows Phone 7.1\References\Microsoft.Live.Controls.dll" を読み込んで使います。
    
    というか、そもそも、Windows8 ストアで動かすとログイン完了で落ちます
    ( Win8 ストアでは、Login する為の単独メソッドがあり、パスワードを間違うとちゃんと反応しますが、ログインがうまく行くと落ちます )
    
    Windows8 ストアアプリは、年額4900円を払って登録しないと専用の API は使用できません。
    
    コード内で使うクラスは、Microsoft.Live.dll を参照します。 Micrsoft のドキュメントでは、同様のものが Windows ストアにもあるような記述がされているのですが、Live SDK v5.4 ではみあたりません。 MainPage.xaml
    <phone:PhoneApplicationPage 
        x:Class="PhoneApp2.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        shell:SystemTray.IsVisible="True"
        xmlns:my="clr-namespace:Microsoft.Live.Controls;assembly=Microsoft.Live.Controls">
    
        <!--LayoutRoot は、すべてのページ コンテンツが配置されるルート グリッドです-->
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    
            <!--TitlePanel は、アプリケーション名とページ タイトルを格納します-->
            <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
                <TextBlock
                    x:Name="ApplicationTitle"
                    Text="Live SDK v5.4"
                    Style="{StaticResource PhoneTextNormalStyle}" />
                <TextBlock
                    x:Name="PageTitle"
                    Text="画像アップロード"
                    Margin="9,-7,0,0"
                    Style="{StaticResource PhoneTextTitle1Style}"
                    FontSize="40"
                    TextWrapping="Wrap" />
            </StackPanel>
    
            <!--ContentPanel - 追加コンテンツをここに入力します-->
            <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
                <my:SignInButton
                    Content="Button"
                    Height="101"
                    HorizontalAlignment="Left"
                    Margin="16,20,0,0"
                    Name="signInButton1"
                    VerticalAlignment="Top"
                    Width="420"
                    ClientId="自分のアプリのクライアントID"
                    SessionChanged="signInButton1_SessionChanged"
                    Scopes="wl.signin wl.basic wl.skydrive_update" />
                <TextBlock
                    Height="301"
                    HorizontalAlignment="Left"
                    Margin="19,127,0,0"
                    Name="infoTextBlock"
                    VerticalAlignment="Top"
                    Width="417"
                    FontSize="22"
                    TextWrapping="Wrap" />
                <Button
                    Content="画像アップロード"
                    Height="96"
                    HorizontalAlignment="Left"
                    Margin="19,434,0,0"
                    Name="button1"
                    VerticalAlignment="Top"
                    Width="417"
                    Click="button1_Click"
                    IsEnabled="False" />
            </Grid>
        </Grid>
     
        <!--ApplicationBar の使用法を示すサンプル コード-->
        <!--<phone:PhoneApplicationPage.ApplicationBar>
            <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
                <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
                <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
                <shell:ApplicationBar.MenuItems>
                    <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
                    <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
                </shell:ApplicationBar.MenuItems>
            </shell:ApplicationBar>
        </phone:PhoneApplicationPage.ApplicationBar>-->
    
    </phone:PhoneApplicationPage>
    
    
    MainPage.xaml.cs
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    using Microsoft.Live;
    using Microsoft.Phone.Tasks;
    using System.Diagnostics;
    
    namespace PhoneApp2
    {
        public partial class MainPage : PhoneApplicationPage
        {
    
            private LiveConnectClient client;
            private LiveConnectSession session;
    
            // コンストラクター
            public MainPage()
            {
                InitializeComponent();
            }
    
            // ****************************************************
            // サインイン・ボタン
            // ****************************************************
            private void signInButton1_SessionChanged(object sender, 
                Microsoft.Live.Controls.LiveConnectSessionChangedEventArgs e)
            {
                if (e.Status == LiveConnectSessionStatus.Connected)
                {
                    session = e.Session;
                    client = new LiveConnectClient(session);
                    infoTextBlock.Text = "サインイン";
                    this.button1.IsEnabled = true;
                }
                else
                {
                    infoTextBlock.Text = "未接続";
                    client = null;
                }
            }
    
            // ****************************************************
            // 画像アップロードボタン
            // ****************************************************
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                // 画像参照オブジェクト
                var picker = new PhotoChooserTask();
                // 画像参照オブジェクトに選択完了のイベントを登録
                picker.Completed +=
                    new EventHandler<PhotoResult>(Image_Selected);
                // 参照開始
                picker.Show();
            }
    
            // ****************************************************
            // 選択完了のイベント
            // ****************************************************
            private void Image_Selected(object sender, PhotoResult e)
            {
                if (e.Error != null)
                {
                    this.infoTextBlock.Text = "画像選択エラー: " + e.Error.ToString();
                }
                else
                {
                    // Windows Phone 内部のパスよりファイル名を取得
                    //string[] filePathSegments = e.OriginalFileName.Split('\\');
                    //string fileName = filePathSegments[filePathSegments.Length - 1];
                    // SkyDrive を処理するオブジェクトにイベントを登録
                    client.UploadCompleted
                        += new EventHandler<LiveOperationCompletedEventArgs>(Live_UploadCompleted);
                    // ****************************************************
                    // アップロード開始
                    // ****************************************************
                    client.UploadAsync("me/skydrive", 
                        "PhotoChooserTask.jpg", 
                        e.ChosenPhoto, 
                        OverwriteOption.Overwrite);
                }
            }
    
            // ****************************************************
            // アップロード完了
            // ****************************************************
            private void Live_UploadCompleted(object sender, LiveOperationCompletedEventArgs e)
            {
                if (e.Error == null)
                {
                    IDictionary<string, object> file = (IDictionary<string, object>)e.Result;
                    this.infoTextBlock.Text = "File uploaded. Link: " + file["source"];
    
                    foreach (var key in file.Keys)
                    {
                        Debug.WriteLine(string.Format("KEY : {0} => VALUE : {1}", key, file[key]));
                    }
                    
                }
                else
                {
                    this.infoTextBlock.Text =
                        "Error uploading file: " + e.Error.ToString();
                }
            }
    
        }
    }
    
    
    
    Windows Phone エミュレータでは、『Pause』キーで、キーボードから英数字が入力可能になります。しかし、US キーボード配置なので、@ は、SHIFT+(2 " ふ) で、_ は、SHIFT+(- = ほ) です。
    ( CTRL+ でも動作するようです )
    
    
    
    
    
    
    
    
    
    アプリは、SkyDrive のページの一番下にある『開発者向け情報(英語)』より登録して、『モバイル クライアント アプリ』を『はい』に設定しておきます。VS2012 で、Form アプリからアクセスする場合もこの設定が必要です。
    
    
    
    ※ Android でテストした時のアプリをそのまま使っています
    
    
    
    
    
    posted by lightbox at 2013-07-12 19:00 | Windows Phone | このブログの読者になる | 更新情報をチェックする
    Seesaa の各ページの表示について
    Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。
    
    Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。
    
    また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。
    
    ※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです
    
    対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。
    
    
    ※ エキスパートモードで表示しています
    
    アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります
    
    
    <% if:page_name eq 'archive' -%>
    アーカイブページでのみ表示される内容
    <% /if %>
    
    <% if:page_name eq 'category' -%>
    カテゴリページでのみ表示される内容
    <% /if %>
    
    <% if:page_name eq 'tag' -%>
    タグページでのみ表示される内容
    <% /if %>
    
    この記述は、以下の場所で使用します
    container 終わり

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

    CSS ドロップシャドウの参考デモ
    BUTTONS (CSS でボタン)
    イラストAC
    ぱくたそ
    写真素材 足成
    フリーフォント一覧
    utf8 文字ツール
    右サイド 終わり
    base 終わり