私はちょうどWCFの使用方法を学んでおり、少しのHelloWorldプログラムをゼロから作成しようとしています(ホスト側とクライアント側の両方)。クライアントがサービスを使用しようとするたびに_ProtocolException Unhandled
_を取得しており、その理由がわかりません。 IISを使用してサービスをホストしています。
私が物事を設定する方法に関して:私はこの video で詳述されているように、そしてこの article 。基本的に、ソリューションごとに異なるプロジェクトがあります。
ここに私が話していることを示すいくつかの異なるファイルがあります:
_namespace HelloWorld
{
public class HelloWorldService : IHelloWorldService
{
public String GetMessage(String name)
{
return "Hello World from " + name + "!";
}
}
}
_
_namespace HelloWorld
{
[ServiceContract]
public interface IHelloWorldService
{
[OperationContract]
String GetMessage(String name);
}
}
_
_namespace HelloWorld
{
public class Proxy : ClientBase<IHelloWorldService>, IHelloWorldService
{
#region IHelloWorldService Members
public String GetMessage(String name)
{
return Channel.GetMessage(name);
}
#endregion
}
_
}
_namespace Client
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click_1(object sender, EventArgs e)
{
Proxy proxy = new Proxy();
MessageBox.Show(proxy.GetMessage(textBox1.Text));
}
}
_
}
クライアントはテキストボックスとボタンを備えた単なるフォームであり、テキストボックスにあるものをパラメーターとして使用してGetMessage()を実行しようとします。フォームのインスタンスを実際に作成する別のクラスがあります。
ここに私のウェブサイトのweb.configがあります:
_<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="HelloWorld.HelloWorldService" behaviorConfiguration="MyServiceTypeBehaviors">
<endpoint address="http://localhost:8002/" binding="basicHttpBinding" contract="HelloWorld.IHelloWorldService"/>
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
</service>
</services>
</system.serviceModel>
</configuration>
_
そして、クライアントに付属するapp.configは次のとおりです。
_<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<endpoint address="http://localhost:8002/" binding="basicHttpBinding" contract="HelloWorld.IHelloWorldService" />
</client>
</system.serviceModel>
</configuration>
_
私のsvcファイルは非常に短いです:
_<%@ServiceHost Service="HelloWorld.HelloWorldService"%>
_
ブラウザで_http://localhost:8002/HelloWorldService.svc
_に移動すると、次のような画面が表示されるため、サービスが実行されていることがわかります。
サービスを作成しました。
このサービスをテストするには、クライアントを作成し、それを使用してサービスを呼び出す必要があります。
そこで、IISを使用してサービスが実行され、テキストボックスとボタンが表示されたウィンドウが起動し、いくつかの文字を入力してボタンを押すと、プログラムがクラッシュし、 ProtocolException Unhandled, (405) Method not allowed.
を取得しますProxyクラスの次の行でエラーが発生します。
_return Channel.GetMessage(name);
_
私は何時間もこれを理解しようとしてきましたが、あまり進歩していません。誰かが少なくとも私を正しい方向に向けることができれば、私はとても感謝しています。
最後に、svcutil.exeを使用せずに、ゼロからクライアントとプロキシを記述したいと思います。
OK、解決策を見つけましたが、なぜそれが機能するのか完全にはわかりません。 CassiniまたはIISまたはWebサイトのホストに使用するものは何でも、web.configファイルのエンドポイントでアドレスを指定することになっていないと思います。それをaddress=""
に変更し、適切に機能し始めたので、サーバーがサービスをホストしているポートがapp.configファイルのコードと一致することを確認してください。
ベースアドレス(.svc)にアクセスすると機能するのは、これがサービスのメタデータを取得するHTTP GET操作だからです。サービスコントラクトでメソッドを呼び出すとき、POST操作を実行していますが、この機能を有効にしていない可能性が高いです。ターゲットにしている.NETバージョンに応じて、赤で強調表示されているこれらのいずれかです。
クライアント構成のエンドポイントタグでサービスの完全なアドレスを指定する必要があります。このような:
<endpoint address="http://localhost:8002/HelloWorldService.svc" binding="basicHttpBinding" contract="HelloWorld.IHelloWorldService" />
エンドポイントタグのアドレス属性のサービス名の後に'。svc'拡張を追加することを忘れないでください。それは私のために働いた。あなたが今すぐ解決策を得ることを願っています。
クライアント構成は次のようになります。
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService"/>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:61569/Service1.svc" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService" contract="WcfServiceApp.IService1" name="WSHttpBinding_IService"/>
</client>
クライアント構成のエンドポイントタグでサービスの完全なアドレスを指定する必要があります
address = "http:// localhost:8002/HelloWorldService.svc"、同じエンドポイント構成を配置します。
私が地獄に閉じ込められている間、それは私のために働いた...