7

我在尝试使用 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);
    }

这可能并不完美,但它似乎按预期工作。

4

2 回答 2

1

您的选项 1) 可以用于 WCF 客户端,因为WebHttpBehavior可以将其应用于 ClientBase(或 ChannelFactory)派生类,如此SO question & answer 中所示。只需将您在 1) 中引用的代码与捕获 500 个响应问题中显示的配置结合起来,它就会显示工作。

于 2012-05-10T18:46:13.100 回答
0

您是否尝试过使用可为空的类型?

object GetStuff(string param, int? top, DateTime? first);
于 2012-05-10T18:52:27.253 回答