QueryStringConverter因未知原因无法正常工作

时间:2016-12-26 21:16:55

标签: c# .net wcf

我正在编写一个为WCF休息服务生成客户端的小型库。但是我遇到了可以为空的值的问题:由于未知原因我的自定义<root> <![CDATA[<xml></xml>]]> </root> 永远不会被调用,我在调试器中看到WCF调用它的QueryStringConverter方法。这是代码:

CanConvert

这里是WCF服务开放:

public class NullableQueryStringConverter : QueryStringConverter
{
    public static NullableQueryStringConverter Instance { get; } = new NullableQueryStringConverter();
    public override bool CanConvert(Type type)
    {
        if (base.CanConvert(type))
            return true;
        var underlyingType = Nullable.GetUnderlyingType(type);
        var canConvert = underlyingType != null && base.CanConvert(underlyingType);
        return canConvert;
    }

    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);
    }
}

正如您所看到的,我正在添加被调用的public void Start(Uri baseAddress) { var serviceInterface = _serviceType.GetInterfaces() .First(i => i.GetCustomAttribute<ServiceContractAttribute>(true) != null); var attribute = _serviceType.GetCustomAttribute<ServiceBehaviorAttribute>(true); if (attribute?.InstanceContextMode == InstanceContextMode.Single) { var singleton = Activator.CreateInstance(_serviceType); ServiceHost = new WebServiceHost(singleton, baseAddress.Concat(_subAddress)); } else { ServiceHost = new WebServiceHost(_serviceType, baseAddress.Concat(_subAddress)); } ServiceHost.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true }); var debugBehavior = ServiceHost.Description.Behaviors.OfType<ServiceDebugBehavior>().FirstOrDefault(); if (debugBehavior != null) { debugBehavior.IncludeExceptionDetailInFaults = true; } else { ServiceHost.Description.Behaviors.Add(new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true }); } var webHttpBinding = new WebHttpBinding { MaxReceivedMessageSize = int.MaxValue, MaxBufferSize = int.MaxValue, MaxBufferPoolSize = int.MaxValue, ReaderQuotas = new XmlDictionaryReaderQuotas { MaxArrayLength = int.MaxValue, MaxStringContentLength = int.MaxValue, MaxDepth = 32 } }; webHttpBinding.ContentTypeMapper = new NewtonsoftJsonContentTypeMapper(); ServiceHost.AddServiceEndpoint(serviceInterface, webHttpBinding, string.Empty); foreach (var endpoint in ServiceHost.Description.Endpoints) { endpoint.Behaviors.Add(new NullableWebHttpBehavior { HelpEnabled = false, DefaultBodyStyle = WebMessageBodyStyle.Bare, DefaultOutgoingRequestFormat = WebMessageFormat.Json, DefaultOutgoingResponseFormat = WebMessageFormat.Json, FaultExceptionEnabled = true }); endpoint.Behaviors.Add(new NewtonsoftJsonBehavior()); } ServiceHost.Open(); } (至少NullableWebHttpBehavior方法),但之后WCF仍需要参数可以通过基类转换。

这是github上项目的链接:link。它很棒,因为我在另一个工作正常的项目中有非常相似的代码。

也许我错过了什么,我不知道。包含要检查的所有逻辑的文件包括:CanConvertNullableWebHttpBehavior.cs。您可以轻松地运行测试(这是此处唯一的测试)并面临同样的问题。

1 个答案:

答案 0 :(得分:1)

经过一番研究后,我发现这种方法会导致异常变成现象:

    protected override IDispatchMessageFormatter GetRequestDispatchFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint)
    {
        if (operationDescription.IsGetOrDeleteOperation())
        {
            // no change for GET operations
            return base.GetRequestDispatchFormatter(operationDescription, endpoint);
        }

        if (operationDescription.Messages[0].Body.Parts.Count == 0)
        {
            // nothing in the body, still use the default
            return base.GetRequestDispatchFormatter(operationDescription, endpoint);
        }

        return new NewtonsoftJsonDispatchFormatter(operationDescription, true);
    }

对于某些原因base.GetRequestDispatchFormatter正在返回原始QueryStringConverter,这会引发错误。所以我刚删除了这些if并始终使用我的自定义NewtonsoftJsonDispatchFormatter,这有一些开销但工作正常。