0

I write a WCF service but I encountered a problem that I can return strings only but cannot return other types. For example I have following service:

[ServiceContract]
public interface IHealthCheckService
{
    [OperationContract]
    int GetDiskCFreeMb();

    [OperationContract]
    string GetDiskCFreeMbAsString();

    [OperationContract]
    float GetAverageCpuPercent();
}

implementation:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
class HealthCheckService : IHealthCheckService, IDisposable
{
    private readonly SystemMonitorClass _monitor;

    public HealthCheckService()
    {
        _monitor = new SystemMonitorClass(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
        _monitor.Start();
    }


    public void Dispose()
    {
        _monitor.Stop();
    }

    public int GetDiskCFreeMb()
    {
        return 17389;
    }

    public string GetDiskCFreeMbAsString()
    {
        return 17389.ToString();
    }

    public float GetAverageCpuPercent()
    {
        return 42;
    }
}

then I call it from Powershell.

$proxy = New-WebServiceProxy -Uri 'http://localhost:29915/healthcheck?wsdl'
$proxy.GetDiskCFreeMb()
$proxy.GetDiskCFreeMbAsString()
$proxy.GetAverageCpuPercent()

When I call it I get following output:

Cannot find an overload for "GetDiskCFreeMb" and the argument count: "0". 
17389
Cannot find an overload for "GetAverageCpuPercent" and the argument count: "0".

Why I get this error and how to fix it?


Service start code:

public partial class HealthCheckMonitorService : ServiceBase
{
    private ServiceHost _host;
    public HealthCheckMonitorService()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {

        StartServiceHost();
    }

    private void StartServiceHost()
    {
        try
        {
            Uri baseAddress = new Uri("http://localhost:29915/healthcheck");
            _host = new ServiceHost(typeof (HealthCheckService), baseAddress);
            AddLog("Default baseAddress = " + baseAddress, EventLogEntryType.Information);
            var smb = new ServiceMetadataBehavior
                      {
                          HttpGetEnabled = true,
                          MetadataExporter =
                          {
                              PolicyVersion = PolicyVersion.Policy15
                          }
                      };
            _host.Description.Behaviors.Add(smb);
            _host.Open();
            AddLog("Host opened on " + baseAddress, EventLogEntryType.Information);
        }
        catch (Exception ex)
        {
            TryCloseHost(_host);
            AddLog(ex.Message, EventLogEntryType.Error);
            throw;
        }
    }
...

wsdl: http://localhost:29915/healthcheck?wsdl

<?xml version="1.0" encoding="UTF8"?>
<wsdl:definitions
    xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
    xmlns:wsa10="http://www.w3.org/2005/08/addressing"
    xmlns:wsp="http://www.w3.org/ns/wspolicy"
    xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract"
    xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
    xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy"
    xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex"
    xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
    xmlns:tns="http://tempuri.org/"
    xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:wsu="http://docs.oasisopen.org/wss/2004/01/oasis200401wsswssecurityutility1.0.xsd"
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://tempuri.org/" name="HealthCheckService">
    <wsdl:types>
        <xsd:schema targetNamespace="http://tempuri.org/Imports">
            <xsd:import namespace="http://tempuri.org/" schemaLocation="http://localhost:29915/healthcheck?xsd=xsd0"/>
            <xsd:import namespace="http://schemas.microsoft.com/2003/10/Serialization/" schemaLocation="http://localhost:29915/healthcheck?xsd=xsd1"/>
        </xsd:schema>
    </wsdl:types>
    <wsdl:message name="IHealthCheckService_GetDiskCFreeMb_InputMessage">
        <wsdl:part name="parameters" element="tns:GetDiskCFreeMb"/>
    </wsdl:message>
    <wsdl:message name="IHealthCheckService_GetDiskCFreeMb_OutputMessage">
        <wsdl:part name="parameters" element="tns:GetDiskCFreeMbResponse"/>
    </wsdl:message>
    <wsdl:message name="IHealthCheckService_GetDiskCFreeMbAsString_InputMessage">
        <wsdl:part name="parameters" element="tns:GetDiskCFreeMbAsString"/>
    </wsdl:message>
    <wsdl:message name="IHealthCheckService_GetDiskCFreeMbAsString_OutputMessage">
        <wsdl:part name="parameters" element="tns:GetDiskCFreeMbAsStringResponse"/>
    </wsdl:message>
    <wsdl:message name="IHealthCheckService_GetAverageCpuPercent_InputMessage">
        <wsdl:part name="parameters" element="tns:GetAverageCpuPercent"/>
    </wsdl:message>
    <wsdl:message name="IHealthCheckService_GetAverageCpuPercent_OutputMessage">
        <wsdl:part name="parameters" element="tns:GetAverageCpuPercentResponse"/>
    </wsdl:message>
    <wsdl:portType name="IHealthCheckService">
        <wsdl:operation name="GetDiskCFreeMb">
            <wsdl:input message="tns:IHealthCheckService_GetDiskCFreeMb_InputMessage" wsam:Action="http://tempuri.org/IHealthCheckService/GetDiskCFreeMb"/>
            <wsdl:output message="tns:IHealthCheckService_GetDiskCFreeMb_OutputMessage" wsam:Action="http://tempuri.org/IHealthCheckService/GetDiskCFreeMbResponse"/>
        </wsdl:operation>
        <wsdl:operation name="GetDiskCFreeMbAsString">
            <wsdl:input message="tns:IHealthCheckService_GetDiskCFreeMbAsString_InputMessage" wsam:Action="http://tempuri.org/IHealthCheckService/GetDiskCFreeMbAsString"/>
            <wsdl:output message="tns:IHealthCheckService_GetDiskCFreeMbAsString_OutputMessage" wsam:Action="http://tempuri.org/IHealthCheckService/GetDiskCFreeMbAsStringResponse"/>
        </wsdl:operation>
        <wsdl:operation name="GetAverageCpuPercent">
            <wsdl:input message="tns:IHealthCheckService_GetAverageCpuPercent_InputMessage" wsam:Action="http://tempuri.org/IHealthCheckService/GetAverageCpuPercent"/>
            <wsdl:output message="tns:IHealthCheckService_GetAverageCpuPercent_OutputMessage" wsam:Action="http://tempuri.org/IHealthCheckService/GetAverageCpuPercentResponse"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="BasicHttpBinding_IHealthCheckService" type="tns:IHealthCheckService">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="GetDiskCFreeMb">
            <soap:operation style="document" soapAction="http://tempuri.org/IHealthCheckService/GetDiskCFreeMb"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="GetDiskCFreeMbAsString">
            <soap:operation style="document" soapAction="http://tempuri.org/IHealthCheckService/GetDiskCFreeMbAsString"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="GetAverageCpuPercent">
            <soap:operation style="document" soapAction="http://tempuri.org/IHealthCheckService/GetAverageCpuPercent"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="HealthCheckService">
        <wsdl:port name="BasicHttpBinding_IHealthCheckService" binding="tns:BasicHttpBinding_IHealthCheckService">
            <soap:address location="http://localhost:29915/healthcheck"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

http://localhost:29915/healthcheck?singleWsdl

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions name="HealthCheckService" targetNamespace="http://tempuri.org/"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy"
    xmlns:wsa10="http://www.w3.org/2005/08/addressing"
    xmlns:tns="http://tempuri.org/"
    xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract"
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
    xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
    xmlns:wsp="http://www.w3.org/ns/ws-policy"
    xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
    xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <wsdl:types>
        <xs:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/"
            xmlns:xs="http://www.w3.org/2001/XMLSchema">
            <xs:element name="GetDiskCFreeMb">
                <xs:complexType>
                    <xs:sequence/>
                </xs:complexType>
            </xs:element>
            <xs:element name="GetDiskCFreeMbResponse">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element minOccurs="0" name="GetDiskCFreeMbResult" type="xs:int"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="GetDiskCFreeMbAsString">
                <xs:complexType>
                    <xs:sequence/>
                </xs:complexType>
            </xs:element>
            <xs:element name="GetDiskCFreeMbAsStringResponse">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element minOccurs="0" name="GetDiskCFreeMbAsStringResult" nillable="true" type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="GetAverageCpuPercent">
                <xs:complexType>
                    <xs:sequence/>
                </xs:complexType>
            </xs:element>
            <xs:element name="GetAverageCpuPercentResponse">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element minOccurs="0" name="GetAverageCpuPercentResult" type="xs:float"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:schema>
        <xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/"
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/">
            <xs:element name="anyType" nillable="true" type="xs:anyType"/>
            <xs:element name="anyURI" nillable="true" type="xs:anyURI"/>
            <xs:element name="base64Binary" nillable="true" type="xs:base64Binary"/>
            <xs:element name="boolean" nillable="true" type="xs:boolean"/>
            <xs:element name="byte" nillable="true" type="xs:byte"/>
            <xs:element name="dateTime" nillable="true" type="xs:dateTime"/>
            <xs:element name="decimal" nillable="true" type="xs:decimal"/>
            <xs:element name="double" nillable="true" type="xs:double"/>
            <xs:element name="float" nillable="true" type="xs:float"/>
            <xs:element name="int" nillable="true" type="xs:int"/>
            <xs:element name="long" nillable="true" type="xs:long"/>
            <xs:element name="QName" nillable="true" type="xs:QName"/>
            <xs:element name="short" nillable="true" type="xs:short"/>
            <xs:element name="string" nillable="true" type="xs:string"/>
            <xs:element name="unsignedByte" nillable="true" type="xs:unsignedByte"/>
            <xs:element name="unsignedInt" nillable="true" type="xs:unsignedInt"/>
            <xs:element name="unsignedLong" nillable="true" type="xs:unsignedLong"/>
            <xs:element name="unsignedShort" nillable="true" type="xs:unsignedShort"/>
            <xs:element name="char" nillable="true" type="tns:char"/>
            <xs:simpleType name="char">
                <xs:restriction base="xs:int"/>
            </xs:simpleType>
            <xs:element name="duration" nillable="true" type="tns:duration"/>
            <xs:simpleType name="duration">
                <xs:restriction base="xs:duration">
                    <xs:pattern value="\-?P(\d*D)?(T(\d*H)?(\d*M)?(\d*(\.\d*)?S)?)?"/>
                    <xs:minInclusive value="-P10675199DT2H48M5.4775808S"/>
                    <xs:maxInclusive value="P10675199DT2H48M5.4775807S"/>
                </xs:restriction>
            </xs:simpleType>
            <xs:element name="guid" nillable="true" type="tns:guid"/>
            <xs:simpleType name="guid">
                <xs:restriction base="xs:string">
                    <xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}"/>
                </xs:restriction>
            </xs:simpleType>
            <xs:attribute name="FactoryType" type="xs:QName"/>
            <xs:attribute name="Id" type="xs:ID"/>
            <xs:attribute name="Ref" type="xs:IDREF"/>
        </xs:schema>
    </wsdl:types>
    <wsdl:message name="IHealthCheckService_GetDiskCFreeMb_InputMessage">
        <wsdl:part name="parameters" element="tns:GetDiskCFreeMb"/>
    </wsdl:message>
    <wsdl:message name="IHealthCheckService_GetDiskCFreeMb_OutputMessage">
        <wsdl:part name="parameters" element="tns:GetDiskCFreeMbResponse"/>
    </wsdl:message>
    <wsdl:message name="IHealthCheckService_GetDiskCFreeMbAsString_InputMessage">
        <wsdl:part name="parameters" element="tns:GetDiskCFreeMbAsString"/>
    </wsdl:message>
    <wsdl:message name="IHealthCheckService_GetDiskCFreeMbAsString_OutputMessage">
        <wsdl:part name="parameters" element="tns:GetDiskCFreeMbAsStringResponse"/>
    </wsdl:message>
    <wsdl:message name="IHealthCheckService_GetAverageCpuPercent_InputMessage">
        <wsdl:part name="parameters" element="tns:GetAverageCpuPercent"/>
    </wsdl:message>
    <wsdl:message name="IHealthCheckService_GetAverageCpuPercent_OutputMessage">
        <wsdl:part name="parameters" element="tns:GetAverageCpuPercentResponse"/>
    </wsdl:message>
    <wsdl:portType name="IHealthCheckService">
        <wsdl:operation name="GetDiskCFreeMb">
            <wsdl:input wsam:Action="http://tempuri.org/IHealthCheckService/GetDiskCFreeMb" message="tns:IHealthCheckService_GetDiskCFreeMb_InputMessage"/>
            <wsdl:output wsam:Action="http://tempuri.org/IHealthCheckService/GetDiskCFreeMbResponse" message="tns:IHealthCheckService_GetDiskCFreeMb_OutputMessage"/>
        </wsdl:operation>
        <wsdl:operation name="GetDiskCFreeMbAsString">
            <wsdl:input wsam:Action="http://tempuri.org/IHealthCheckService/GetDiskCFreeMbAsString" message="tns:IHealthCheckService_GetDiskCFreeMbAsString_InputMessage"/>
            <wsdl:output wsam:Action="http://tempuri.org/IHealthCheckService/GetDiskCFreeMbAsStringResponse" message="tns:IHealthCheckService_GetDiskCFreeMbAsString_OutputMessage"/>
        </wsdl:operation>
        <wsdl:operation name="GetAverageCpuPercent">
            <wsdl:input wsam:Action="http://tempuri.org/IHealthCheckService/GetAverageCpuPercent" message="tns:IHealthCheckService_GetAverageCpuPercent_InputMessage"/>
            <wsdl:output wsam:Action="http://tempuri.org/IHealthCheckService/GetAverageCpuPercentResponse" message="tns:IHealthCheckService_GetAverageCpuPercent_OutputMessage"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="BasicHttpBinding_IHealthCheckService" type="tns:IHealthCheckService">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="GetDiskCFreeMb">
            <soap:operation soapAction="http://tempuri.org/IHealthCheckService/GetDiskCFreeMb" style="document"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="GetDiskCFreeMbAsString">
            <soap:operation soapAction="http://tempuri.org/IHealthCheckService/GetDiskCFreeMbAsString" style="document"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="GetAverageCpuPercent">
            <soap:operation soapAction="http://tempuri.org/IHealthCheckService/GetAverageCpuPercent" style="document"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="HealthCheckService">
        <wsdl:port name="BasicHttpBinding_IHealthCheckService" binding="tns:BasicHttpBinding_IHealthCheckService">
            <soap:address location="http://localhost:29915/healthcheck"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

you can see that output types are correct

Alex Zhukovskiy
  • 9,565
  • 11
  • 75
  • 151
  • 1
    Can you post a class that implements the `IHealthCheckService` interface? – Chmiel123 Sep 09 '15 at 11:18
  • As you wish. It doesn't have any complex logic here. `_monitor` usings can be safely removed, they do nothing in this example. Their deleting does not affect this result – Alex Zhukovskiy Sep 09 '15 at 11:28
  • What about if you try it direct in a browser? I can't remember what the URL convention is for accessing via browser but maybe just try `http://localhost:29915/healthcheck?wsdl` and see if you get links to the functions – musefan Sep 09 '15 at 11:33
  • How do you run this service? Through visual studio? If you have HealthCheckService.svc selected in Solution Explorer and debug, it will automatically open WcfTestClient. You can also open WcfTestClient from: C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\WcfTestClient.exe – Chmiel123 Sep 09 '15 at 11:34
  • @Chmiel123 I run it through windows service, so see an edit, please. – Alex Zhukovskiy Sep 09 '15 at 11:48
  • Have you tried naming your operation contracts ? For example: `[OperationContract(Name = "GetDiskCFreeMb")]` – Morgan M. Sep 09 '15 at 11:52
  • try reading this Q&A http://stackoverflow.com/q/6343376/520612 – CB. Sep 09 '15 at 11:55
  • 2
    @CB. omg, it did the thing. Post is as answer, please, because I didn't find this in google and it may be useful for future successors. Or even mark it as duplicate. `[XmlSerializerFormat]` fix the problem. – Alex Zhukovskiy Sep 09 '15 at 11:59

0 Answers0