微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在WCF Web编程模型中,如何用一组查询字符串参数(即同名)编写一个操作契约?

使用WCF Web编程模型可以指定如下操作契约:
[OperationContract]
[WebGet(ResponseFormat = Webmessageformat.Xml,UriTemplate = "SomeRequest?qs1={qs1}&qs2={qs2}")]
XElement SomeRequest1(string qs1,string qs2);

现在,如果我们必须签署一个接受一个同名的参数的数组(在这种情况下是qs1),那么合同就是这样…

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

当我们对方法进行调用时,我们在运行时得到错误消息:

the query string must have ‘name=value’ pairs with unique names. Note that the names are case-insensitive. See the documentation for UriTemplate for more details.

如何定义使用参数数组暴露资源的HTTP服务,而不使用loosey-goosey接口?

解决方法

我实现了一个简单的自定义QueryStringConverter,以便您可以使qs1为字符串[],然后将查询字符串变量用逗号分隔(例如 http://server/service/SomeRequest?qs1=val1,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处理string []参数:

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

注意:microsoft connect中存在与该代码直接相关的错误.在几乎所有情况下,您尝试查询转换不同类型的代码实际上不起作用.

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

请确保您仔细阅读,浪费您的时间创建自定义REST查询字符串转换器的时间,无法工作. (适用于Framework 4.0及以下).

原文地址:https://www.jb51.cc/html/230144.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐