‘C#’ カテゴリーのアーカイブ

WPFで長時間かかる処理の間にUIのイベントを処理させるには

2010年7月11日 日曜日

WPFでWindows FormのApplication.DoEventsメソッドと同様に長時間かかる処理の間にUIのイベントを処理させるには、下記のように行う。(MSDNより)

[SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public void DoEvents()
{
    DispatcherFrame frame = new DispatcherFrame();
    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
        new DispatcherOperationCallback(ExitFrame), frame);
    Dispatcher.PushFrame(frame);
}

public object ExitFrame(object f)
{
    ((DispatcherFrame)f).Continue = false;

    return null;
}

WCFを使ってXML-RPC通信を行うには

2010年6月10日 木曜日

Xml-Rpc With WCFから「XML-RPC for WCF」をダウンロード。

上記blogのコメントに従ってXmlRpcDataContractSerializationHelperクラスのDeserializeStructメソッドのループ           

while (reader.NodeType != XmlNodeType.EndElement)
 {

の最後に、下記を追加。(ホワイトスペースと改行(XmlNodeType.Text)をスキップするため)

while (reader.NodeType == XmlNodeType.Whitespace || reader.NodeType == XmlNodeType.Text)
 {
            reader.Skip();
 }

また、Desirializeメソッドでswitch (reader.LocalName)の case XmlRpcProtocol.DateTime:の日付の形式が、dateTime.iso8601の形式(下記例参照)でなかったため修正。

<dateTime.iso8601>19980717T14:08:55</dateTime.iso8601>

また、Desirializeメソッドで<value>の内側に型のタグがない場合stringにする処理がなかったため、メソッドの一番最後に

 else if (reader.NodeType == XmlNodeType.Text)
{
        returnValue = reader.ReadString(); 
}

を追加した。このモジュールの使う手順は下記。

  • 参照にMicrosoft.Samples.XmlRpcを追加。
  • 普通のWCFと同じようにServiceContract, OperationContract属性を追加したインターフェースを定義する。ただし、OperationContractは[OperationContract(Action = "metaWeblog.newPost")]のようにActionにXML-RPCのメソッド名を追加する。また、XML-RPCのstruct型の定義はWCF側ではクラスとして定義し、DataContract, DataMember属性を追加する。
  • Web.configのsystem.serviceModelセクションを下記のように定義する。

<system.serviceModel>
   <extensions>
     <behaviorExtensions>
       <add name=”xmlRpcEndpointBehavior”
            type=”Microsoft.Samples.XmlRpc.XmlRpcEndpointBehaviorSection, Microsoft.Samples.XmlRpc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null” />
     </behaviorExtensions>
   </extensions>
   <services>
     <service behaviorConfiguration=”debugBehavior” name=”実装したクラス名”>
       <host>
       </host>
       <endpoint address=”" behaviorConfiguration=”xmlRpcBehavior” binding=”webHttpBinding”
         contract=”定義したインタフェース名” />
     </service>
   </services>
   <behaviors>
     <endpointBehaviors>
       <behavior name=”xmlRpcBehavior”>
         <xmlRpcEndpointBehavior />
       </behavior>
     </endpointBehaviors>
     <serviceBehaviors>
       <behavior name=”debugBehavior”>
         <serviceMetadata httpGetEnabled=”true” />
         <serviceDebug includeExceptionDetailInFaults=”true” />
       </behavior>
     </serviceBehaviors>
   </behaviors>
   <serviceHostingEnvironment multipleSiteBindingsEnabled=”true” />
 </system.serviceModel>

ASP.Net MVC 2の主な新機能

2010年4月25日 日曜日
○HTMLヘルパーを使ってフォームのコントロールを出力するときにIDの文字列を渡す必要がなくなった
今までは
<%= Html.TextBox(“ProductName”, model.ProductName) %>
と書いて
<input id=”ProductName” name=”ProductName” type=”text” value=”xxxxxx” />
のように出力していたが、下記のようにIDの文字列を渡す必要がなくなった。
<%= Html.TextBoxFor(model => model.ProductName) %>
○モデルクラスのプロパティにAttributeをつけることによってバリデーションをサーバ、クライアントの双方でできるようになった
System.ComponentModel.DataAnnotations名前空間下にある下記のAttributeが使用可能。
[Required]、[StringLength]、[Range]、[RegularExpression]
以下使用例。
[Required(ErrorMessage = "名前を入力してください。")]
[StringLength(50, ErrorMessage = "50文字以内です。")]
[Range(0, 120, ErrorMessage = "入力できる数字は0から120までです。")]
[ReqularExpression("^[0-9]{3}-?[0-9]{4}$”, ErrorMessage = “”]
クライアントでもチェックできるようにするにはViewに

<script src=”Scripts/MicrosoftAjax.js” type=”text/javascript></script>
<script src=”Scripts/MicrosoftMvcValidation.js” type=”text/javascript></script>

<% Html.EnableClientValidation(); %>

の3行を追加する。

ADO.Net Entity Frameworkのようにツールで自動生成するモデルを使っている場合は、
自動生成時に属性がなくならないように下記のようにする。
まずPartialクラスのファイルにMetadataType属性を追加する。

[[MetadataType(typeof(PersonMetadata))]
public partial class Person
{
}

次にメタデータクラスを追加して、プロパティに対してバリデーションを設定する。

[Bind(Exclude="ID")]
public class PersonMetadata
{
     [Required(ErrorMessage = "名前を入力してください。")]
     public string Name { get; set; }
}

ValidationAttributeクラスを継承したクラスを作ることによって、独自の検証属性を作ることも可能。

○Actionメソッドでデフォルト値を使えるようになった。
{controller}/{action}/{id}
のようなUrlの時に、

public ActionResult View(int id, [DefaultValue(1)]int page) {
  }

のような使い方が可能。

○非同期コントローラのサポート
非同期コントローラを使うことで負荷の高いサイトでサーバがスレッドプールを使い果たしてしまうのを防げる。

参考サイト

http://www.asp.net/learn/whitepapers/what-is-new-in-aspnet-mvc/

http://www.atmarkit.co.jp/fdotnet/scottgublog/20100113aspnetmvc2/aspnetmvc2.html

C#とIronPython 2.6の連携方法(変数の受け渡し方)

2010年2月20日 土曜日

IronPythonのインストールディレクトリにあるIronPython.dll, Microsoft.Scripting.dll, Microsoft.Scripting.Core.dll, Nicrosoft.Dynamic.dllに参照を通す。

下記のソースコードのような方法でC#のコードからPythonのスクリプトの実行と変数の値のやりとりが可能。

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Scripting.Hosting;
using IronPython.Hosting;

    public class Class1
    {
        public IronPython.Runtime.List Val1;
        public IronPython.Runtime.List Val2;
    }
    class Program
    {
        static void Main(string[] args)
        {
             ScriptEngine engine = Python.CreateEngine();
             ScriptSource source = engine.CreateScriptSourceFromString(
@”print obj1.Val1
result = obj1.Val2″);
             ScriptScope scope = engine.CreateScope();
             var obj1 = new Class1()
             {
                 Val1 = new IronPython.Runtime.List { 1, “abc” },
                 Val2 = new IronPython.Runtime.List { 2, “def”}
             };
             scope.SetVariable(“obj1″, obj1);
             source.Execute(scope);
             object[] result = scope.GetVariable<IronPython.Runtime.List>(“result”).ToArray();
             Console.WriteLine(“{0},{1}”, result[0], result[1]);
        }

    }

ADO.Net Entity Frameworkでストアドプロシジャを実行するには

2009年12月9日 水曜日
  1. Visual Studioエンティティデザイナでコンテキストメニューを開いて、「データベースモデルからモデルを更新」を実行し、実行したいストアドプロシジャを追加する。
  2. モデルブラウザから「EntityContainer->関数インポート」上でコンテキストメニューを開いて、「関数インポートの作成」実行する。
  3. 「関数インポートの追加」ウィンドウが表示されるので、ストアドプロシジャ名を選択し、関数インポート名、戻り値の型を設定する。
  4. 関数インポートが追加される。
  5. Entity Clientを利用して、インポートした関数を実行する。

 using (EntityConnection conn =
    new EntityConnection(“name=AdventureWorksEntities”))
{
    conn.Open();
    try
    {
        // Create an EntityCommand.
        using (EntityCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = “AdventureWorksEntities.GetOrderDetails”;
            cmd.CommandType = CommandType.StoredProcedure;
            EntityParameter param = new EntityParameter();
            param.Value = “43659″;
            param.ParameterName = “SalesOrderHeaderId”;
            cmd.Parameters.Add(param);

            // Execute the command.
            using (EntityDataReader rdr =
                cmd.ExecuteReader(CommandBehavior.SequentialAccess))
            {
                // Read the results returned by the stored procedure.
                while (rdr.Read())
                {
                    Console.WriteLine(“Header#: {0} “ +
                    “Order#: {1} ProductID: {2} Quantity: {3} Price: {4}”,
                    rdr[0], rdr[1], rdr[2], rdr[3], rdr[4]);
                }
            }
        }
    }
    catch (EntityException ex)
    {
        Console.WriteLine(ex.ToString());
    }
    conn.Close();
}

.Net frameworkのSyndicationFeedクラスを使ってYahoo Media RSS(MRSS)などの拡張フィードを取得するには

2009年11月27日 金曜日

SyndicationFeedに含まれるSyndicationItemのElementExtensionsプロパティを使って取得可能。

たとえば下記のように、サムネールを取得することが可能である。

        private static readonly XNamespace NS_YAHOO_MEDIA_RSS = “http://search.yahoo.com/mrss/“;

        public static string GetThubmnailUri(SyndicationItem item)
        {
            var extensions = item.ElementExtensions.Where<SyndicationElementExtension>(
               obj => obj.OuterNamespace == NS_YAHOO_MEDIA_RSS).ToArray();
            XmlReader reader = extensions[0].GetReader();
            XElement topElem = (XElement)XElement.ReadFrom(reader);
            XElement thumbElem = topElem.Elements(NS_YAHOO_MEDIA_RSS + “thumbnail”).FirstOrDefault();
            if (thumbElem != null)
            {
                XAttribute attr = thumbElem.Attribute(“url”);
                if (attr != null)
                {
                    return attr.Value;
                }
            }
            return string.Empty;
        }

.Net(C#)でRSS, Atomなどのフィードを取得/作成するには

2009年11月27日 金曜日

System.ServiceModel.Syndication.SyndicationFeedクラスを使用する。System.ServiceModel.Web.dll クラスを参照することが必要となる。フィードの取得は下記のように行う。

using (XmlReader reader = XmlReader.Create(“フィードのURI”))
            {
                SyndicationFeed feed = SyndicationFeed.Load(reader);
                SyndicationItem[] itemList = feed.Items.ToArray();
            }

これでitemListにフィードのエントリを格納したSyndicationItemの配列が返される。

フィードの作成にはSyndicationFeed クラスを利用してフィードを作成し、Atom10FeedFormatterクラス を利用してシリアライズするとAtom形式になり、Rss20FeedFormatter クラスを利用してシリアライズするとRSS2.0形式になる。