如何使QueryStringConverter解析字节枚举名称

时间:2017-06-20 12:46:41

标签: c# wcf enums webhttpbinding

我的网络服务使用msdn)来公开REST界面。有些方法接受枚举作为参数; e.g:

[ServiceContract]
public partial interface IStrangeEnumDemo
{        
    [OperationContract]
    [WebGet(UriTemplate = "DefaultEnumName?q={val}")]
    string DefaultEnumName(DefaultNumberEnum val);
}

DefaultNumberEnum

// Note values in this Enum are not annotated with [System.RunTime.Serialization.EnumMember] or [System.Runtim.Serialization.DataContract], both are not needed
public enum DefaultNumberEnum
{
    APPLE,
    PEAR,
    BANANA
}

该操作的实现是:

public partial class StrangeEnumDemo : IStrangeEnumDemo
{
    public string DefaultEnumName(DefaultNumberEnum val)
    {
        return $"Fruit: {val.ToString()}";
    }
}

根据MSDN documentation of QueryStringConverterOhad Schneider's answerCan I pass non-string to WCF RESTful service using UriTemplate?Carlos Figueira's MSDN blogQueryStringConverter应将枚举名称转换为其值。< / p>

通过以下方式调用网络服务:

  

http://localhost:16772/StrangeEnumDemo.svc/DefaultEnumName?q=PEAR

按预期产生响应 1

  

“水果:梨子”

我想用作参数的另一个枚举由byte支持; e.g:

public enum ByteEnum: byte
{
    ALIGATOR,
    BEAR,
    ZEBRA
}

操作声明和实现几乎与DefaultNumber enum:

相同
[ServiceContract]
public partial interface IStrangeEnumDemo
{
    [OperationContract]
    [WebGet(UriTemplate = "ByteEnumName?q={val}")]
    string ByteEnumName(ByteEnum val);
}

public partial class StrangeEnumDemo : IStrangeEnumDemo
{
    public string ByteEnumName(ByteEnum val)
    {
        return $"Animal: {val.ToString()}";
    }
}

然而,在致电时:

  

http://localhost:16772/StrangeEnumDemo.svc/ByteEnumName?q=BEAR

我收到:

<Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">
    <Code>
    <Value>Receiver</Value>
    <Subcode>
        <Value xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</Value>
    </Subcode>
    </Code>
    <Reason>
    <Text xml:lang="nl-NL">Input string was not in a correct format.</Text>
    </Reason>
    <Detail>
    <ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <HelpLink i:nil="true"/>
        <InnerException i:nil="true"/>
        <Message>Input string was not in a correct format.</Message>
        <StackTrace>   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer&amp; number, NumberFormatInfo info, Boolean parseDecimal)&#xD;
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)&#xD;
   at System.Byte.Parse(String s, NumberStyles style, NumberFormatInfo info)&#xD;
   at System.ServiceModel.Dispatcher.QueryStringConverter.ConvertStringToValue(String parameter, Type parameterType)&#xD;
   at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)&#xD;
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc&amp; rpc)&#xD;
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)&#xD;
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)&#xD;
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc)&#xD;
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</StackTrace>
        <Type>System.FormatException</Type>
    </ExceptionDetail>
    </Detail>
</Fault>

为了完整性,这是我的service.svc:

<%@ ServiceHost Language="C#" Debug="true" Service="StrangeEnumBehavior.StrangeEnumDemo" CodeBehind="StrangeEnumDemo.svc.cs" %>

这是我的web.config:

<?xml version="1.0"?>
<configuration>
    <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
    </appSettings>
    <!--
        For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367.

        The following attributes can be set on the <httpRuntime> tag.
            <system.Web>
                <httpRuntime targetFramework="4.7" />
            </system.Web>
    -->
    <system.web>
        <compilation debug="true" targetFramework="4.7"/>
        <httpRuntime targetFramework="4.7"/>
    </system.web>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior>
                    <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
                    <serviceDebug includeExceptionDetailInFaults="true"/>
                </behavior>
            </serviceBehaviors>
            <endpointBehaviors>
                <behavior>
                    <webHttp automaticFormatSelectionEnabled="true" faultExceptionEnabled="true"/>
                </behavior>
            </endpointBehaviors>
        </behaviors>
        <protocolMapping>
            <add binding="webHttpBinding" scheme="http"/>
        </protocolMapping>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="false"/>
    </system.serviceModel>
    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
        <!--
                To browse web app root directory during debugging, set the value below to true.
                Set to false before deployment to avoid disclosing web app folder information.
            -->
        <directoryBrowse enabled="true"/>
    </system.webServer>
</configuration>

是否有办法让QueryStringConverter解析字节枚举值的名称与使用隐式后备存储解析枚举的方法相同?

我提出的解决方案是使用具有隐式后备存储的不同枚举,并使用数据合同并手动转换(或使用data contract surrogate进行自动转换);但我宁愿不复制枚举。

原始枚举必须存储为一个字节。

1 我使用标头Accept: application/json让服务返回JSON数据。

0 个答案:

没有答案