В модели веб-программирования WCF, как можно написать контракт операции с массивом параметров строки запроса (то есть с тем же именем)?

13
задан Peter Mortensen 25 July 2015 в 00:16
поделиться

3 ответа

Я реализовал простой пользовательский QueryStringConverter так, чтобы можно было сделать qs1, строка [] затем имеет переменную строки запроса быть разграниченной запятой (например, http://server/service/SomeRequest?qs1=val1,val2,val3,val4 )

[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Xml,
        UriTemplate = "SomeRequest?qs1={qs1}")]
XElement SomeRequest2(string[] qs1);

Первый, Вам нужен класс, который наследовался WebHttpBehavior так, чтобы мы могли ввести наш пользовательский QueryStringConverter:

public class CustomHttpBehavior : System.ServiceModel.Description.WebHttpBehavior
{
    protected override System.ServiceModel.Dispatcher.QueryStringConverter GetQueryStringConverter(System.ServiceModel.Description.OperationDescription operationDescription)
    {
        return new CustomQueryStringConverter();
    }
}

Затем наш CustomQueryStringConverter, который обрабатывает строку [] параметры:

public class CustomQueryStringConverter : System.ServiceModel.Dispatcher.QueryStringConverter
{
    public override bool CanConvert(Type type)
    {
        if (type == typeof(string[]))
        {
            return true;
        }

        return base.CanConvert(type);
    }

    public override object ConvertStringToValue(string parameter, Type parameterType)
    {
        if (parameterType == typeof(string[]))
        {
            string[] parms = parameter.Split(',');
            return parms;
        }

        return base.ConvertStringToValue(parameter, parameterType);
    }

    public override string ConvertValueToString(object parameter, Type parameterType)
    {
        if (parameterType == typeof(string[]))
        {
            string valstring = string.Join(",", parameter as string[]);
            return valstring;
        }

        return base.ConvertValueToString(parameter, parameterType);
    }
}

последняя вещь, которую необходимо сделать, создают расширение конфигурации поведения так, чтобы время выполнения могло получить экземпляр CustomWebHttpBehavior:

public class CustomHttpBehaviorExtensionElement : System.ServiceModel.Configuration.BehaviorExtensionElement
{
    protected override object CreateBehavior()
    {
        return new CustomHttpBehavior();
    }

    public override Type BehaviorType
    {
        get { return typeof(CustomHttpBehavior); }
    }
}

Теперь мы добавляем элемент к нашим расширениям конфигурации так, чтобы наш CustomWebHttpBehavior использовался, мы используем Название того расширения вместо <webHttp /> в нашем поведении:

 <system.serviceModel>
   <services>
     <service name="NameSpace.ServiceClass">
       <endpoint address="" behaviorConfiguration="MyServiceBehavior"
        binding="webHttpBinding" contract="NameSpace.ServiceClass" />
     </service>
   </services>
  <behaviors>
   <endpointBehaviors>
    <behavior name="MyServiceBehavior">
      <customWebHttp/>
    </behavior>
   </endpointBehaviors>
  </behaviors>
  <extensions>
    <behaviorExtensions>
      <add name="customWebHttp" type="NameSpace.CustomHttpBehaviorExtensionElement, MyAssemblyName" />
    </behaviorExtensions>
  </extensions>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
 </system.serviceModel>

можно теперь также расширить CustomQueryStringConverter для обработки других типов, которые значение по умолчанию каждый не делает, такие как nullable типы значения.

ПРИМЕЧАНИЕ: существует ошибка, зарегистрированная в подключении Microsoft, которое непосредственно касается этого кода. Код на самом деле не работает при почти всех обстоятельствах, где Вы пытаетесь Запросить, Преобразовывают различные типы.

http://connect.microsoft.com/VisualStudio/feedback/details/616486/bug-with-getquerystringconverter-not-being-called-by-webservicehost#tabs

удостоверьтесь, что Вы читаете это тщательно перед тем, чтобы тратить впустую часы Вашего времени, создавая пользовательские преобразователи строки запроса REST, которые не могут возможно работать. (Относится к Платформе 4.0 и ниже).

27
ответ дан Jim 25 July 2015 в 10:16
поделиться

Ответить на Ваш комментарий к моему другому ответу:

можно сделать подстановочный параметр в конце querystring как

[WebGet(ResponseFormat = WebMessageFormat.Xml,
        UriTemplate = "SomeRequest?qs1={*qs1}")]
XElement SomeRequest2(string qs1);

Этот способ, которым qs1 строковый параметр будет целыми сырыми данными querystring после qs1 =, Вы могли затем проанализировать это вручную в Вашем коде.

QueryStringConverter полагается на форматирование querystring, настолько делающего что-то точно, как Вы хотите, не возможно, возможно не переписывая QueryStringConverter вместо небольших переопределений, которые мы сделали в другом ответе.

Из MSDN:

сегменты Wildcard должны следовать следующим правилам:

  • может быть самое большее один именованный подстановочный сегмент для каждой шаблонной строки.
  • названный подстановочный сегмент А должен появиться в самом правом сегменте в пути.
  • названный подстановочный сегмент А не может сосуществовать с анонимным подстановочным сегментом в той же шаблонной строке.
  • название именованного подстановочного сегмента должно быть уникальным.
  • Именованные подстановочные сегменты не могут иметь значений по умолчанию.
  • Именованные подстановочные сегменты не могут закончиться “/”.
5
ответ дан joshperry 25 July 2015 в 10:16
поделиться
  • 1
    Оба ответа кажутся странными мне. Сначала - почему использование Cygwin, когда SVN может быть легко скомпилирован для Windows также? Второй - Черепаха AFAIK является расширением оболочки, и это не работает хорошо от Карты памяти... – Vilx- 29 March 2009 в 07:11

Имейте в виду, что в WCF 3.5 необходимо указать полное квалифицированное название сборки в:

   <extensions>
    <behaviorExtensions>
      <add name="customWebHttp" type="NameSpace.CustomHttpBehaviorExtensionElement, MyAssemblyName, NOT SUFFICIENT HERE" />
    </behaviorExtensions>
  </extensions>

Просто так: SampleService.CustomBehavior, SampleService, Version=1.0.0.0, Culture=нейтрально, PublicKeyToken=null

Иначе вы получите исключение:

Ошибка конфигурации
. Описание: Произошла ошибка при обработке конфигурационного файла, необходимого для обслуживания этого запроса. Пожалуйста, ознакомьтесь с подробной информацией об ошибке и внесите соответствующие изменения в конфигурационный файл.

Сообщение об ошибке парсера: Неверный элемент в конфигурации. Имя расширения 'CustomWebHttp' не зарегистрировано в коллекции по адресу system.serviceModel/extensions/behaviorExtensions.

2
ответ дан 1 December 2019 в 19:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: