我在尝试使用 WCF 使用简单服务时遇到问题。到目前为止,一切都很顺利,除了实现可选的查询字符串参数。界面看起来有点像这样:
[ServiceContract]
[XmlSerializerFormat]
public interface IApi
{
[OperationContract]
[WebGet(UriTemplate = "/url/{param}?top={top}&first={first}")]
object GetStuff(string param, int top, DateTime first);
}
然后通过创建一个继承的类来消耗它ClientBase<IApi>
。我尝试了几种使参数可选的方法:
1)使参数可以为空
这没有用。我收到来自QueryStringConverter
另一个问题的类似消息:WCF 服务合同可以有一个可为空的输入参数吗?
2)URL末尾的一个参数
因此,我考虑将 UriTemplate 更改为更通用,构建查询字符串并将其作为参数传递。这似乎也不起作用,因为传入的值被编码,因此服务器不会将其识别为查询字符串。
例子:
[WebGet(UriTemplate = "/url/{query}")]
3) 黑客解决方案
到目前为止,我发现使它起作用的唯一方法是将所有参数更改为字符串,并且此处似乎允许使用 NULL。
例子:
[WebGet(UriTemplate = "/url/{param}?top={top}&first={first}")]
object GetStuff(string param, string top, string first);
这个接口的消费仍然接受正确的变量类型,但是ToString
被使用了。这些查询字符串参数仍然出现在实际请求中。
那么,有没有办法在使用WCF 使用 REST 服务时,使查询字符串参数成为可选?
更新 - 如何修复
采纳了创建服务行为的建议。这继承自WebHttpBehaviour
. 它看起来如下:
public class Api : ClientBase<IApi>
{
public Api() : base("Binding")
{
Endpoint.Behaviors.Add(new NullableWebHttpBehavior());
}
}
NullableWebHttpBehavior
可以在以下 Stackoverflow 问题中找到:WCF服务合同可以有一个可为空的输入参数吗?. 唯一的问题是,ConvertValueToString
没有超载,所以我快速做了一个:
public override string ConvertValueToString(object parameter, Type parameterType)
{
var underlyingType = Nullable.GetUnderlyingType(parameterType);
// Handle nullable types
if (underlyingType != null)
{
var asString = parameter.ToString();
if (string.IsNullOrEmpty(asString))
{
return null;
}
return base.ConvertValueToString(parameter, underlyingType);
}
return base.ConvertValueToString(parameter, parameterType);
}
这可能并不完美,但它似乎按预期工作。