1

私は以下のサービス契約を結んでいます。

[ServiceContract]
public interface IWebProxyService
{
    [OperationContract]
    string GetSomeData();
}

コントラクトでこの属性も試しました。

[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, UriTemplate = "/GetFormsBaseUrl")] 

サービス参照/契約なしで別のアプリケーションからこれを呼び出すことは可能ですか?

私は(呼び出し元のアプリから)次のバリエーションの束を試しました:

 public static void GetSomeData(string webServiceProxyURL)
    {
        WebRequest request = WebRequest.Create(webServiceProxyURL);
        request.Method = "GET";
        request.ContentType = "application/json";
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        Stream dataStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(dataStream);
        string responseFromServer = reader.ReadToEnd();
        Console.WriteLine("Response: \n" + responseFromServer);

    }

"The remote server returned an error: (400) Bad Request" というメッセージが表示されます。Web 例外ステータスは「System.Net.WebExceptionStatus.ProtocolError」です。何が間違っていますか?他のアプリから WCF メソッドを呼び出すにはどうすればよいですか?

4

2 に答える 2

2

コードのように実行して、そのような応答を取得することはできません。「不正な要求」は、要求が WCF が期待するものに準拠していないことを WCF が伝えているだけです。すべての WCF 呼び出しは、メッセージが SOAP 形式であることを想定しています。そうでない場合、サーバーは呼び出しを認識できません。サービス コントラクトに 1 つではなく 2 つのメソッドがある場合、そのような要求を送信するときに、WCF はどのメソッドを呼び出すべきかをどのように判断するのでしょうか。答えは、(ツールによって生成されるか、ChannelFactory を使用して自分で作成した) クライアント プロキシを使用して WCF を呼び出すと、要求は SOAP メッセージにカプセル化されます。このメッセージには、呼び出すエンドポイントを WCF が識別できるようにするためのより多くの情報が含まれます。 、呼び出すメソッド、および指定したパラメーター。

クライアント側のプロキシ クラスの使用を避けたい場合 (理由は言わなかったので、適切な理由があると思います)、理論的には、自分で SOAP メッセージを作成し、http ヘッダーに埋め込んで送信することができます。 http Web リクエスト。ただし、これは明らかに私が推奨するアプローチではありません。

サービス コントラクトを制御できる場合は、Web サービスに RESTful API を実装することを検討できます。これにより、「http://yourserver.com/getdata」のような通常の http URL を使用してサービスにアクセスできるようになります。ほとんどの場合、RESTful サービスの実装は WCF で非常に簡単です。サービス コントラクトに属性を追加するだけです。このようなものに変更します(属性を追加するだけです)

[ServiceContract]
public interface IWebProxyService
{
    [OperationContract]
    [WebGet(UriTemplate="getData")]
    string GetSomeData();
}

次に、以下のように、webHttpBinding を使用するようにサービスを構成します。

<configuration>
   <system.serviceModel>
     <services>
        <service name="...">
            <endpoint binding="webHttpBinding" contract="..."
                      behaviorConfiguration="webHttp"/>
        </service>
     </services>
     <behaviors>
        <endpointBehaviors>
            <behavior name="webHttp">
                <webHttp/>
            </behavior>
        </endpointBehaviors>
     </behaviors>
  </system.serviceModel>
<configuration>

次に、クライアント側から、サービス コントラクトを使用せずに、通常の WebRequest だけで Web サービスにアクセスできます。サービス uri の末尾に「/getData」を追加する必要があり、応答は xml 形式です。

RESTful api を使用すると、単純な URL を使用して、より多くのこと (パラメーターの提供、データの変更など) を実行できます。WCF RESTful api のチュートリアルについては、このを参照してください。または、MSDN を検索してください。

編集: 安静な API が機能することを確認するためのコードを記述する必要さえありません。Web ブラウザーを起動して、サーバーからの応答を確認するだけでテストに最適です。

于 2013-10-14T23:43:33.050 に答える
0

以下は答えではなく、太ったコメントです。OPがそれを読むのに十分長く残っていることを願っています.

IDisposableコードの大きな問題の 1 つは、オブジェクトを適切に処理していないことです。これにより、リソース リークが発生します。次のことを試してください。

public static void GetSomeData(string webServiceProxyURL)
{
    var request = WebRequest.Create(webServiceProxyURL);
    request.Method = "GET";
    request.ContentType = "application/json";
    string responseFromServer = "No response from server";
    using (var response = (HttpWebResponse) request.GetResponse())
    {
        using (var dataStream = response.GetResponseStream())
        {
            if (dataStream != null)
            {
                using (var reader = new StreamReader(dataStream))
                {
                    responseFromServer = reader.ReadToEnd();
                }
            }
        }
    }
    Console.WriteLine("Response: \n" + responseFromServer);
}
于 2013-10-14T23:49:26.767 に答える