Подтвердить что ты не робот

Ошибка WCF webHttpBinding с параметрами метода. "Не более одного параметра тела можно сериализовать без элементов обертки"

Операция '' контракта '' указывает несколько запросить параметры тела сериализован без оболочки элементы. Не более одного параметра тела может быть сериализована без обертки элементы. Либо удалите лишнее тело параметров или установить BodyStyle собственности на WebGetAttribute/WebInvokeAttribute для Облаченный.

Я пытаюсь открыть службу WCF С# 4.0 с помощью JSON через следующую конфигурацию (установленную с помощью редактора конфигурации 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);

Это работает; но это возможно только для параметров типа String. Как мне отрегулировать это для моих других функций, таких как:

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

Пробовал много поисковых запросов Google, но оказался пустым, любая помощь была оценена.

Приветствия,

Ник.

4b9b3361

Ответ 2

Проблема заключается в том, что ваш UriTemplate должен указать все передаваемые значения, кроме одного. Хорошо иметь сложные типы, отличные от строк, в качестве параметров, мы часто отправляем легкие json-объекты в наши сервисы, и они в порядке. Вот пример с использованием вашего последнего примера.

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

Будет работать, потому что в него передается только один параметр, и ожидается, что он будет находиться в теле сообщения, потому что он не передается как параметр URL, но вы можете передавать только один параметр тела (параметр, переданный в тело сообщения, а не URL-адрес).

Вы можете изменить свой первый метод, подобный этому

[OperationContract]
[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "login/{UserName}")]
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);

Это имеет смысл? В основном все переданные значения должны быть представлены как параметр URL, за исключением одного, который может быть передан в тело сообщения. Если вам нужно несколько значений, переданных в тело сообщения, сделайте легкий объект с несколькими значениями, которые вам нужны, и примите этот объект целиком в теле сообщения.

Ответ 3

WCF не поддерживает более одного параметра с открытым телом, если вам нужно пройти несколько параметров в одной операции метода post, то нам нужно установить BodyStyle в Wrapped.

Итак, в вашем случае вам нужно будет сменить свой рабочий контракт на следующее:

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

Источник: Нажмите здесь