如何编写带有查询字符串参数数组

如何编写带有查询字符串参数数组

本文介绍了在WCF网络编程模型中,如何编写带有查询字符串参数数组(即具有相同名称)的操作协定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用WCF Web编程模型,可以这样指定操作合同:

Using the WCF web programming model one can specify an operation contract like so:

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

现在,如果我们必须签订这样的合同,该合同接受具有相同名称的参数数组(在本例中为 qs1 ),就像这样...

Now if we had to make a contract that accepts an array of parameters with the same name (in this case qs1) contract like so...

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

调用该方法时,会在运行时收到错误消息:

We get the error message at run time when we make the invocation to the method:

如何定义一种HTTP服务,该服务公开带有一组参数的资源而不诉诸于松散的鹅颈式接口?

How does one define an HTTP service that exposes a resource with an array of parameters without resorting to a loosey-goosey interface?

推荐答案

我实现了一个简单的自定义QueryStringConverter,因此您可以将qs1设置为字符串[],然后将查询字符串变量用逗号分隔(例如 http://server/service/SomeRequest?qs1 = val1,val2,val3,val4 )

I've implemented a simple custom QueryStringConverter so that you can make qs1 an string[] then have the query string variable be comma delimited (e.g. http://server/service/SomeRequest?qs1=val1,val2,val3,val4)

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

首先,您需要一个继承自WebHttpBehavior的类,以便我们可以注入自定义的QueryStringConverter:

First you need a class that inherits from WebHttpBehavior so that we can inject our custom QueryStringConverter:

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

然后我们的处理字符串[]参数的CustomQueryStringConverter:

Then our CustomQueryStringConverter that handles string[] parameters:

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的实例:

The last thing you need to do is create a behavior configuration extension so that the runtime can get an instance of the 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 />:

Now we add the element to our configuration extensions so that our CustomWebHttpBehavior is used, we use the Name of that extension instead of <webHttp /> in our behavior:

 <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来处理默认类型所不具备的其他类型,例如可为空的值类型.

You can now also extend your CustomQueryStringConverter to handle other types that the default one doesn't, such as nullable value types.

注意:在Microsoft connect上记录了一个与该代码直接相关的错误.在几乎所有尝试查询转换不同类型的情况下,该代码实际上都无法正常工作.

NOTE: There is a bug logged at microsoft connect that directly relates to this code. The code does not actually work in almost all circumstances where you attempt to Query Convert different types.

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

请确保在浪费大量时间创建无法正常工作的自定义REST查询字符串转换器之前,请仔细阅读此内容. (适用于Framework 4.0及更低版本).

Please make sure you read this carefully before wasting hours of your time creating custom REST query string converters that cannot possibly work. (Applies to Framework 4.0 and below).

这篇关于在WCF网络编程模型中,如何编写带有查询字符串参数数组(即具有相同名称)的操作协定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 01:44