Deploying WCF Tutorial App on IIS7: "The type could not be found"

Jimmy picture Jimmy · Apr 29, 2010 · Viewed 59k times · Source

I've been trying to follow this tutorial for deploying a WCF sample to IIS . I can't get it to work. This is a hosted site, but I do have IIS Manager access to the server. However, in step 2 of the tutorial, I can't "create a new IIS application that is physically located in this application directory". I can't seem to find a menu item, context menu item, or what not to create a new application. I've been right-clicking everywhere like crazy and still can't figure out how to create a new app. I suppose that's probably the root issue, but I tried a few other things (described below) just in case that actually is not the issue. Here is a picture of what I see in IIS Manager, in case my words don't do it justice:

No add Application Here http://www.freeimagehosting.net/uploads/d6edbaaf3c.png

This is "deployed" at http://test.com.cws1.my-hosting-panel.com/IISHostedCalcService/Service.svc . The error says:

    The type 'Microsoft.ServiceModel.Samples.CalculatorService', 
provided as the Service attribute value in the ServiceHost directive, 
or provided in the configuration element
 system.serviceModel/serviceHostingEnvironment/serviceActivations 
could not be found.

I also tried to create a virtual dir (IISHostedCalc) in dotnetpanel that points to IISHostedCalcService . When I navigate to http://test.com.cws1.my-hosting-panel.com/IISHostedCalc/Service.svc , then there is a different error:

This collection already contains an address with scheme http.  
There can be at most one address per scheme in this collection.

Interestingly enough, if I click on View Applications, it seems like the virtual directory is an application (see image below)... although, as per the error message above, it doesn't work.

Is this an app or not? http://www.freeimagehosting.net/uploads/f3230be046.png

As per the tutorial, there was no compiling involved; I just dropped the files on the server as follow inside the folder IISHostedCalcService:

service.svc
Web.config
<dir: App_Code>
   Service.cs

service.svc contains:

<%@ServiceHost language=c# Debug="true" Service="Microsoft.ServiceModel.Samples.CalculatorService"%>

(I tried with quotes around the c# attribute, as this looks a little strange without quotes, but it made no difference)

Web.config contains:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="Microsoft.ServiceModel.Samples.CalculatorService">

        <!-- This endpoint is exposed at the base address provided by host:                                        http://localhost/servicemodelsamples/service.svc  -->
        <endpoint address=""
                  binding="wsHttpBinding"
                  contract="Microsoft.ServiceModel.Samples.ICalculator" />

        <!-- The mex endpoint is explosed at http://localhost/servicemodelsamples/service.svc/mex -->
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>
  </system.serviceModel>
  <system.web>
    <customErrors mode="Off"/>
  </system.web>
</configuration>

Service.cs contains:

using System;
using System.ServiceModel;

namespace Microsoft.ServiceModel.Samples
{

    [ServiceContract]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double n1, double n2);
        [OperationContract]
        double Subtract(double n1, double n2);
        [OperationContract]
        double Multiply(double n1, double n2);
        [OperationContract]
        double Divide(double n1, double n2);
    }


    public class CalculatorService : ICalculator
    {
        public double Add(double n1, double n2)
        {
            return n1 + n2;
        }
        public double Subtract(double n1, double n2)
        {
            return n1 - n2;
        }
        public double Multiply(double n1, double n2)
        {
            return n1 * n2;
        }
        public double Divide(double n1, double n2)
        {
            return n1 / n2;
        }
    }
}

Answer

Jimmy picture Jimmy · Apr 30, 2010

Well, it seems I got this to work. I still can't find the "Create Application" item in IIS Manager. That part is kind of frustrating, but I'm glad it appears to be working anyway.

I had create the physical directory IISHostedCalcService under wwwroot. That was creating some confusion; it meant that http://test.com.cws1.my-hosting-panel.com/IISHostedCalcService/Service.svc was almost working, but it shouldn't. I moved IISHostedCalcService outside wwwroot and now the only place to access the service is http://test.com.cws1.my-hosting-panel.com/IISHostedCalc/Service.svc .

Then, accessing http://test.com.cws1.my-hosting-panel.com/IISHostedCalc/Service.svc was throwing that "This collection already contains an address with scheme http.
There can be at most one address per scheme in this collection." error. It turns out the solution to that is to add the following to the web.config file, right under system.serviceModel:

<serviceHostingEnvironment>
  <baseAddressPrefixFilters>
    <add prefix="http://test.com.cws1.my-hosting-panel.com"/>
  </baseAddressPrefixFilters>
</serviceHostingEnvironment>

After that I got a new error when ccessing http://test.com.cws1.my-hosting-panel.com/IISHostedCalc/Service.svc : "The contract name IMetadataExchange could not be found in the list of contracts implemented by the service CalculatorService". It turns out the solution to that is to modify the web.config file as follows (i.e., add the behaviors section, and behaviorConfiguration="SimpleServiceBehavior" in the service element):

<configuration>
  <system.serviceModel>
    <serviceHostingEnvironment>
      <baseAddressPrefixFilters>
        <add prefix="http://test.com.cws1.my-hosting-panel.com"/>
      </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
    <services>
      <service name="Microsoft.ServiceModel.Samples.CalculatorService" behaviorConfiguration="SimpleServiceBehavior">
      ...
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="SimpleServiceBehavior">
          <serviceMetadata httpGetEnabled="True" policyVersion="Policy15" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <system.web>
    <customErrors mode="Off"/>
  </system.web>
</configuration>

Finally, I was able to create client proxies by pointing svcutil at http://test.com.cws1.my-hosting-panel.com/IISHostedCalc/service.svc?wsdl in step 5c of the tutorial at http://msdn.microsoft.com/en-us/library/ms733133.aspx . However, when I ran the client, I got a "The caller was not authenticated by the service" error. The solution to this was the simplest: just change binding="wsHttpBinding" to binding="basicHttpBinding" in the service's web.config and the client's web.config (or re-run svcutil after changing the service's web.config).

The web.config ended up looking like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <serviceHostingEnvironment>
      <baseAddressPrefixFilters>
        <add prefix="http://test.com.cws1.my-hosting-panel.com"/>
      </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
    <services>
      <service name="Microsoft.ServiceModel.Samples.CalculatorService" behaviorConfiguration="SimpleServiceBehavior">

        <!-- This endpoint is exposed at the base address provided by host:                                        http://localhost/servicemodelsamples/service.svc  -->
        <endpoint address=""
                  binding="basicHttpBinding"
                  contract="Microsoft.ServiceModel.Samples.ICalculator" />

        <!-- The mex endpoint is explosed at http://localhost/servicemodelsamples/service.svc/mex -->            
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />

      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="SimpleServiceBehavior">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true" policyVersion="Policy15" />
          <!-- 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="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <system.web>
    <customErrors mode="Off"/>
  </system.web>
</configuration>