次の方法で共有


方法: AJAX 対応 ASP.NET Web サービスを WCF に移行する

このトピックでは、基本 ASP.NET AJAX サービスを、同等の AJAX 対応 Windows Communication Foundation (WCF) サービスに移行する手順を説明します。 ここでは、ASP.NET AJAX サービスの、機能的に同等の WCF バージョンを作成する方法を示します。 この 2 つのサービスを並行して使用するか、WCF サービスを ASP.NET AJAX サービスと置き換えて使用することができます。

既存の ASP.NET AJAX サービスを WCF AJAX サービスに移行すると、次のような利点が得られます。

  • 最小限の追加構成で、AJAX サービスを SOAP サービスとして公開できます。

  • トレースなどの WCF の機能の利点が得られます。

次の手順では、Visual Studio 2012 を使用していることを前提としています。

手順に続く例で、ここで説明する手順によって作成されるコードを示します。

AJAX 対応エンドポイントを介した WCF サービスの公開の詳細については、「方法: 構成を使用して ASP.NET AJAX エンドポイントを追加する」トピックを参照してください。

ASP.NET Web サービス アプリケーションを作成してテストする

  1. Visual Studio 2012 を開きます。

  2. [ファイル] メニューの [新規作成] をクリックし、 [プロジェクト][Web] の順にクリックしてから [ASP.NET Web サービス アプリケーション] を選択します。

  3. プロジェクトに ASPHello という名前を付け、 [OK] をクリックします。

  4. Service1.asmx.cs ファイルで、System.Web.Script.Services.ScriptService] が含まれた行のコメントを解除し、このサービスに対して AJAX を有効にします。

  5. [ビルド] メニューの [ソリューションのビルド] を選択します。

  6. [デバッグ] メニューから [デバッグなしで開始] を選択します。

  7. 生成された Web ページで、HelloWorld 操作を選択します。

  8. HelloWorld テスト ページで [起動] をクリックします。 次の XML 応答を受信します。

    <?xml version="1.0" encoding="utf-8" ?>
    <string xmlns="http://tempuri.org/">Hello World</string>
    
  9. この応答は、ASP.NET AJAX サービスが現在機能していること、およびこのサービスが現在 Service1.asmx/HelloWorld でエンドポイントを公開していることを確認するものです。このエンドポイントが HTTP POST 要求に応答し、XML を返します。

    これで、このサービスを変換して WCF AJAX サービスを使用する準備ができました。

同等の WCF AJAX サービス アプリケーションを作成するには

  1. ASPHello プロジェクトを右クリックし、 [追加][新しい項目][AJAX 対応 WCF サービス] の順にクリックします。

  2. サービスに WCFHello という名前を付け、 [追加] をクリックします。

  3. WCFHello.svc.cs ファイルを開きます。

  4. Service1.asmx.cs から、HelloWorld 操作の次の実装をコピーします。

    public string HelloWorld()
    {
        return "Hello World";
    }
    
  5. コピーした HelloWorld 操作の実装を、WCFHello.svc.cs ファイルの次のコードの場所に貼り付けます。

    public void DoWork()
    {
          // Add your operation implementation here
          return;
    }
    
  6. ServiceContractAttributeNamespace 属性を WCFHello として指定します。

    [ServiceContract(Namespace="WCFHello")]
    [AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Required)]
    public class WCFHello
    { … }
    
  7. WebInvokeAttributeHelloWorld 操作に追加し、Xml を返すように ResponseFormat プロパティを設定します。 この設定を行わない場合、既定の戻り値の型は Json です。

    [OperationContract]
    [WebInvoke(ResponseFormat=WebMessageFormat.Xml)]
    public string HelloWorld()
    {
        return "Hello World";
    }
    
  8. [ビルド] メニューの [ソリューションのビルド] を選択します。

  9. WCFHello.svc ファイルを開き、 [デバッグ] メニューの [デバッグなしで開始] を選択します。

  10. これで、サービスが WCFHello.svc/HelloWorld でエンドポイントを公開します。このエンドポイントが HTTP POST 要求に応答します。 HTTP POST 要求をブラウザーからテストすることはできませんが、エンドポイントは次の XML を返します。

    <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Hello World</string>
    
  11. これで、WCFHello.svc/HelloWorldService1.aspx/HelloWorld エンドポイントが機能的に同等になりました。

このトピックで説明した手順によって作成されるコードを次の例に示します。

//This is the ASP.NET code in the Service1.asmx.cs file.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
using System.Web.Script.Services;

namespace ASPHello
{
    /// <summary>
    /// Summary description for Service1.
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
    [System.Web.Script.Services.ScriptService]
    public class Service1 : System.Web.Services.WebService
    {

        [WebMethod]
        public string HelloWorld()
        {
            return "Hello World";
        }
    }
}

//This is the WCF code in the WCFHello.svc.cs file.
using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;

namespace ASPHello
{
    [ServiceContract(Namespace = "WCFHello")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class WCFHello
    {
        // Add [WebInvoke] attribute to use HTTP GET.
        [OperationContract]
        [WebInvoke(ResponseFormat=WebMessageFormat.Xml)]
        public string HelloWorld()
        {
            return "Hello World";
        }

        // Add more operations here and mark them with [OperationContract].
    }
}

XmlDocument 型は、DataContractJsonSerializer によってシリアル化できないため、XmlSerializer ではサポートされていません。 XDocument 型を使用するか、DocumentElement をシリアル化します。

ASMX Web サービスが WCF サービスと並行してアップグレードおよび移行される場合は、クライアントで 2 つの型を、同じ名前に割り当てないようにします。 同じ名前が割り当てられていると、WebMethodAttributeServiceContractAttribute で同じ型が使用されている場合に、シリアライザーで次のような例外が発生します。

  • 最初に WCF サービスが追加された場合は、ASMX Web サービスでメソッドを呼び出すと、ConvertValue(Object, Type, String) で例外が発生します。これは、プロキシでの順序の定義で WCF スタイル定義が優先されるためです。

  • ASMX Web サービスが最初に追加された場合は、WCF サービスでメソッドを呼び出すと、DataContractJsonSerializer で例外が発生します。これは、プロキシでの順序の定義で Web サービス スタイル定義が優先されるためです。

DataContractJsonSerializer と ASP.NET AJAX JavaScriptSerializer の動作には大きな違いがあります。 たとえば、DataContractJsonSerializer はディクショナリをキーと値のペアの配列として表しますが、ASP.NET AJAX JavaScriptSerializer はディクショナリを実際の JSON オブジェクトとして表します。 したがって、ASP.NET AJAX では、ディクショナリが次のように表されます。

Dictionary<string, int> d = new Dictionary<string, int>();
d.Add("one", 1);
d.Add("two", 2);

このディクショナリは、JSON オブジェクトでは次のように表されます。

DataContractJsonSerializer は、キーの種類が文字列ではないディクショナリを処理でき、JavaScriptSerializer はできません。この点で前者はより強力と言えます。 しかし、後者の方が JSON で使いやすいと言えます。

これらのシリアライザーの主な違いを次の表に示します。

相違点のカテゴリ DataContractJsonSerializer ASP.NET AJAX JavaScriptSerializer
空きバッファー (新しい byte[0]) の Object (または Uri、あるいは他の一部のクラス) への逆シリアル化 SerializationException null
Value のシリアル化 {} (または {"__type":"#System"}) [Null]
[Serializable] 型のプライベート メンバーのシリアル化 できるか シリアル化できません
ISerializable 型のパブリック プロパティのシリアル化 シリアル化できません できるか
JSON の「拡張機能」 オブジェクト メンバー名で引用符を必要とする ({"a":"hello"}) JSON 仕様に準拠しています。 引用符のないオブジェクト メンバー名 ({a:"hello"}) をサポートします。
DateTime 協定世界時刻 (UTC) "\/Date(123456789U)\/" および "\/Date(\d+(U|(\+\-[\d{4}]))?)\\/)" の形式はサポートされていません。 DateTime 値として、"\/Date(123456789U)\/" および "\/Date(\d+(U|(\+\-[\d{4}]))?)\\/)" の形式がサポートされています。
ディクショナリの表現 KeyValuePair<K,V> の配列。文字列以外のキーの種類を処理します。 実際の JSON オブジェクトですが、文字列の種類のキーのみ処理します。
エスケープ文字 必ず、エスケープ文字であるスラッシュ (/) を付けます。"\n" などのエスケープされない無効な JSON 文字は使用できません。 DateTime 値には、エスケープ文字スラッシュ (/) を付けます。

関連項目