web-dev-qa-db-ja.com

メソッドパラメータでのWCF webHttpBindingエラー。 「ラッパー要素なしで最大1つのbodyパラメーターをシリアル化できます」

操作 '' of contract ''は、ラッパー要素なしでシリアル化される複数のリクエストボディパラメーターを指定します。ラッパー要素なしで、最大1つのbodyパラメーターをシリアル化できます。余分な本体パラメーターを削除するか、WebGetAttribute/WebInvokeAttributeのBodyStyleプロパティをWrappedに設定します。

次の構成(WCF構成エディターで設定)を介してJSONでC#4.0 WCFサービスを公開しようとしています。

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="iPhoneAPI.API">
        <endpoint address="" behaviorConfiguration="NewBehavior0" binding="webHttpBinding"
          bindingConfiguration="" contract="iPhoneAPI.IApi" />
      </service>
    </services>
    <protocolMapping>
      <add scheme="http" binding="webHttpBinding" bindingConfiguration="" />
    </protocolMapping>
    <behaviors>
      <endpointBehaviors>
        <behavior name="NewBehavior0">
          <webHttp defaultOutgoingResponseFormat="Json" />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>  
</configuration>

/API.svcにアクセスすると、前述の例外メッセージが表示されます。

次の(パラメーターのない)契約のみを指定すると、サービスは機能します。

[OperationContract]
[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "test")]
GenericApiResult<IEnumerable<LiveFeedEntity>> test();

非文字列のパラメーターを必要とするメソッドがある場合、前述の例外が発生します。

例:

[OperationContract]
[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "login")]
LoginApiResult Login(String UserName, String Password);

この関数を次のように変更すると:

[OperationContract]
[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "login/{UserName}/{Password}")]
LoginApiResult Login(String UserName, String Password);

できます;ただし、これは文字列タイプのパラメーターでのみ可能です。以下のような他の機能のためにこれをどのように再ポーリングしますか?

[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "logout")]
GenericApiResult<bool> Logout(Guid SessionKey);

多くのグーグル検索を試してみましたが、手ぶらで見つけました。どんな助けもありがたいです。

乾杯、

ニック。

31
NKCSS

エラーが推奨するように WebInvokeAttribute.BodyStyleWrapped に設定しようとしましたか?

38
Oppositional

問題は、UriTemplateが1つを除いて渡されるすべての値を指定する必要があることです。パラメーターとして文字列以外の複雑な型を使用するのは問題ありません。軽量のjsonオブジェクトを頻繁にサービスに送信し、それらは正常に受信されます。最後の例を使用した例を次に示します。

[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "logout")]
GenericApiResult<bool> Logout(Guid SessionKey);

渡されるパラメーターは1つだけであり、URLパラメーターとして渡されないため、投稿本文にあることが期待されますが、1つの本文パラメーター( URLではなく投稿)。

このように最初の方法を変更できます

[OperationContract]
[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "login/{UserName}")]
LoginApiResult Login(String UserName, String Password);

それは機能しますが、パスワードは投稿本文に含まれます。この特定の例での最良の方法は、2番目の例で行ったことを次のようにすることです。

[OperationContract]
[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "login/{UserName}/{Password}")]
LoginApiResult Login(String UserName, String Password);

それは理にかなっていますか?基本的に、渡されるすべての値は、投稿本文で渡すことができるものを除き、URLパラメーターとして表す必要があります。投稿本文に複数の値を渡す必要がある場合は、必要な複数の値を持つ軽量オブジェクトを作成し、投稿本文でそのオブジェクト全体を受け入れます。

23
ljkyser

WCFは裸のボディで複数のパラメーターをサポートしていません。1つのpostメソッド操作で複数のパラメーターを渡す必要がある場合は、BodyStyleWrappedに設定する必要があります。

したがって、あなたの場合、運用契約を次のように変更する必要があります。

[WebInvoke(Method = "POST", UriTemplate = "evals", BodyStyle = WebMessageBodyStyle.WrappedRequest)]
[OperationContract]
void SubmitVideoPOST(Video videoArg, string userId);

ソース: ここをクリック

6
Ankit