Search code examples
web-serviceswcfinterface

WCF webservice fails after "extracting interface"


I am new to WebServices, and have a simple question.

I wrote a "Hello World" Service with Visual Studio 2017: ServiceAjax.svc.cs:

namespace WebServiceTest
{    
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class ServiceAjax
    {
        [OperationContract]
        [WebGet]
        public string DoWork()
        {
            return "Hallo World";
        }
    }
}

the ServiceAjax.svc reads as this:

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

Running this works fine.

Now i read it's the way to go to declare an Interface for the Service. Nearly every example does this ..., so i tried:

ServiceAjax.svc.cs:

namespace WebServiceTest
{
    [ServiceContract]
    public interface IServiceAjax
    {
        [OperationContract]
        [WebGet]
        string DoWork();

    }  

      [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class ServiceAjax: IServiceAjax
    {
        public string DoWork()
        {
            return "Hallo World";
        }
    }
}

Running this i get an error: It's german, so my translation might be not excatly as the english message: "From http://localhost:58513/ServiceAjax.svc no metadata could be loaded ..." I Little bit below he tells me: WebServiceTest.ServiceAjax wos not found in the List of contracts implemented by ServiceAjax

So, it must be a dump foult, cause i cant explain why extracting an Interface blows the Service, i sure missed something simple.

But i cant find a difference to the "simple WCF Web HTTP Service" samples in the net.

Ideas?

Update: I added this to an existing ASPX-Project, not a "clean" wcf Project ....


Solution

  • I found the answer myself (after earning the Tumbleweed badge ...)

    There was one line missing in the WebConfig

          <endpoint address="mex" 
                    binding="mexHttpBinding" 
                    name="mex" 
                    contract="IMetadataExchange" /> 
    

    I had tried with different "Factorys" in the SVC-Markup, which did not work. Perhaps havent found the right one ... i.e.

    <%@ServiceHost language=c# Debug="true" Service="WebServiceTest.ServiceAjax"  
    Factory=System.ServiceModel.Activation.WebScriptServiceHostFactory%> 
    

    Adding the Config manually and adding to it did the trick after all. I followed the steps in

    https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-configuration-to-add-an-aspnet-ajax-endpoint

    This lead to the "cant load metadata" Problem which i could fix with the line on Top (mex endpoint). Why mircosoft [sic] did not point that out, i dont know ... And why this starts beeing needed when using an interface i dont know neither. But I stumbled about more occasions, when he needed that, i.e, AJAX Scripting Manger, which needs the Namespace-Argument in the Servicedeclaration too:

    [ServiceContract(Namespace = "AJAXService")]
    

    Below what i added to web.config (allready included Lines where dropped 4 shortage

    <system.serviceModel>   
      <behaviors>
        <serviceBehaviors>
          <behavior name="myServiceTypeBehaviors" >
            <serviceMetadata httpGetEnabled="true" />
          </behavior>
        </serviceBehaviors>
        <endpointBehaviors>
          <behavior name="myDataAspNetAjaxBehavior">
            <enableWebScript />
          </behavior>
        </endpointBehaviors>
      </behaviors>
      <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
       multipleSiteBindingsEnabled="true" />
      <services>
        <service behaviorConfiguration="myServiceTypeBehaviors"
          name="WebServiceTest.ServiceAjax">
           <endpoint address="" 
                    behaviorConfiguration="myDataAspNetAjaxBehavior"
                    binding="webHttpBinding" 
                    name="ZESData" 
                    contract="WebServiceTest.IZESData" />
          <endpoint address="mex" 
                    binding="mexHttpBinding" 
                    name="mex" 
                    contract="IMetadataExchange" /> 
        </service>
      </services>
    </system.serviceModel>