WCF服务合同可以有一个可以为空的输入参数吗?
我的合同定义如下:
[OperationContract] [WebGet(UriTemplate = "/GetX?myStr={myStr}&myX={myX}", BodyStyle = WebMessageBodyStyle.Wrapped)] string GetX(string myStr, int? myX);
我得到一个例外:[InvalidOperationException:合同’IMyGet’中的’GetX’操作有一个名为’myX’的查询变量,类型为’System.Nullable 1[System.Int32]', but type 'System.Nullable
1 [System.Int32 ”不能通过’QueryStringConverter’转换。 UriTemplate查询值的变量必须具有可由“QueryStringConverter”转换的类型。
找不到任何有关此错误的信息,除了以下链接: http : //blog.rolpdog.com/2007/07/webget-and-webinvoke-rock.html这有点旧 ,而不是解决方案。
任何想法除了摆脱可以为空的参数做什么?
谢谢。
是的,您可以使用WCF获得可为空的参数。 我认为你的问题是QueryStringConverter不能使用可空参数。
该怎么办? 您需要使用UriTemplate属性吗? 如果您将其发布为“经典Web服务”,那么您就不会遇到此问题。
另一个选项是遵循你提供的链接中的建议 – 即接收myX参数作为字符串,然后将其转换为int?,其中(例如)“n”为空。 不漂亮。
这个问题有一个解决方案,不需要任何黑客攻击。 它可能看起来像很多工作,但它并不是真的,如果你仔细阅读它会很有意义。 问题的核心是确实存在未解决的错误 (从.NET 4开始),这意味着WebServiceHost不使用自定义QueryStringConverters。 因此,您需要做一些额外的工作,并了解WebHttpEndpoints的WCF配置如何工作。 下面为您提供了解决方案。
首先,自定义QueryStringConverter允许在查询字符串中提供空值,方法是省略它们,或提供空字符串:
public class NullableQueryStringConverter : QueryStringConverter { public override bool CanConvert(Type type) { var underlyingType = Nullable.GetUnderlyingType(type); return (underlyingType != null && base.CanConvert(underlyingType)) || base.CanConvert(type); } public override object ConvertStringToValue(string parameter, Type parameterType) { var underlyingType = Nullable.GetUnderlyingType(parameterType); // Handle nullable types if (underlyingType != null) { // Define a null value as being an empty or missing (null) string passed as the query parameter value return String.IsNullOrEmpty(parameter) ? null : base.ConvertStringToValue(parameter, underlyingType); } return base.ConvertStringToValue(parameter, parameterType); } }
现在是一个自定义WebHttpBehavior ,它将设置自定义QueryStringConverter来代替标准QueryStringConverter 。 请注意,此行为派生自WebHttpBehavior ,这很重要,以便我们inheritanceREST端点所需的行为:
public class NullableWebHttpBehavior : WebHttpBehavior { protected override QueryStringConverter GetQueryStringConverter(OperationDescription operationDescription) { return new NullableQueryStringConverter(); } }
现在是一个自定义ServiceHost ,它将自定义行为添加到WebHttpEndpoint,以便它将使用自定义QueryStringConverter 。 在此代码中需要注意的重要一点是,它派生自ServiceHost而非 WebServiceHost 。 这很重要,否则上面提到的错误将阻止使用自定义QueryStringConverter :
public sealed class NullableWebServiceHost : ServiceHost { public NullableWebServiceHost() { } public NullableWebServiceHost(object singletonInstance, params Uri[] baseAddresses) : base(singletonInstance, baseAddresses) { } public NullableWebServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses) { } protected override void OnOpening() { if (this.Description != null) { foreach (var endpoint in this.Description.Endpoints) { if (endpoint.Binding != null) { var webHttpBinding = endpoint.Binding as WebHttpBinding; if (webHttpBinding != null) { endpoint.Behaviors.Add(new NullableWebHttpBehavior()); } } } } base.OnOpening(); } }
因为我们不是从WebServiceHost派生的,所以我们需要这样做,并确保我们的配置正确,以确保REST服务能够正常工作。 您需要的就是以下内容。 在此配置中,我还有一个WS HTTP端点设置,因为我需要从C#(使用WS HTTP作为其更好的)和移动设备(使用REST)访问此服务。 如果不需要,可以省略此端点的配置。 需要注意的一件重要事情是,您不再需要自定义端点行为。 这是因为我们现在正在添加自己的自定义端点行为,该行为绑定自定义QueryStringConverter 。 它派生自WebHttpBehavior ,这是配置添加的内容,使其现在变得多余。
最后要做的是创建一个自定义ServiceHostFactory并告诉svc文件使用它,这将导致使用所有自定义代码。 当然你也可以创建一个自定义元素,允许你在配置中添加行为,但我认为对于这种行为,基于代码的方法更好,因为你不太可能想要删除处理可空类型的能力,因为它会破坏你的服务:
public sealed class NullableWebServiceHostFactory : ServiceHostFactory { protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) { return new NullableWebServiceHost(serviceType, baseAddresses); } }
将Service.svc文件的标记更改为以下内容:
<%@ ServiceHost Service="MyNamespace..Service1" CodeBehind="Service1.svc.cs" Factory="MyNamespace.NullableWebServiceHostFactory" %>
现在,您可以在服务接口中使用可空类型而不会出现任何问题,只需省略参数或将其设置为空字符串即可。 以下资源可能对您有更多帮助:
希望这可以帮助!
实际上……你绝对可以拥有可以为空的参数,或者QueryStringConverter
不支持的任何其他类型的参数。 您需要做的就是扩展QueryStringConverter
以支持您需要的任何类型。 请参阅本文中接受的答案==>
在WCF Web编程模型中,如何使用查询字符串参数数组(即具有相同名称)编写操作契约?
嗯,快速解决方案(不太漂亮)是在WCF各自的接口和服务代码中接受可空参数作为字符串。
上述就是C#学习教程:WCF服务合同可以有一个可以为空的输入参数吗?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/998930.html