views:

2088

answers:

2

I have read several articles on what needs to be done to successfully host a WCF service on GoDaddy.

--UPDATE-- I've abandoned the GoDaddy hosting option, and am hosting this with FluidHosting.com. They seem pretty solid, and all the issues below are still valid... --END UPDATE--

I have since implemented these:

  • adding remove name... before add name...
  • added whHttp binding
  • added ScriptHandlerFactory
  • added ScriptHandlerFactoryAppServices
  • added .svc handler
  • added Factory="WcfWebService1.CustomHostFactory" to the service's markup definition
  • added a CustomHostFactory and CustomHost class to Service1.svc.cs

I've gone from a 500 server error, to a few other minor ones and now stuck on:

The resource cannot be found.

Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

Requested URL: /testbed1/Service1.svc

I also have an index.htm file located therein, and can go directly to it. Only when I try to access Service1.svc, I receive this error.

Below is my web.config:

<?xml version="1.0"?>
<!--
    Note: As an alternative to hand editing this file you can use the 
    web admin tool to configure settings for your application. Use
    the Website->Asp.Net Configuration option in Visual Studio.
    A full list of settings and comments can be found in 
    machine.config.comments usually located in 
    \Windows\Microsoft.Net\Framework\v2.x\Config 
-->
<configuration>


  <configSections>
    <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
        <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
        <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
          <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere" />
          <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
          <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
          <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
        </sectionGroup>
      </sectionGroup>
    </sectionGroup>
  </configSections>


  <appSettings/>
  <connectionStrings/>

  <system.web>
    <!--
            Set compilation debug="true" to insert debugging 
            symbols into the compiled page. Because this 
            affects performance, set this value to true only 
            during development.
        -->

    <compilation debug="false">
      <buildProviders>
        <add extension=".svc" type="System.ServiceModel.Activation.ServiceBuildProvider, 
                System.ServiceModel, Version=3.0.0.0, Culture=neutral,
                PublicKeyToken=b77a5c561934e089"/>
      </buildProviders>
      <assemblies>
        <add assembly="System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
        <add assembly="System.ServiceModel.Web, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
        <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </assemblies>

    </compilation>
    <!--
            The <authentication> section enables configuration 
            of the security authentication mode used by 
            ASP.NET to identify an incoming user. 
    -->
    <authentication mode="Windows" />

    <!--
            The <customErrors> section enables configuration 
            of what to do if/when an unhandled error occurs 
            during the execution of a request. Specifically, 
            it enables developers to configure html error pages 
            to be displayed in place of a error stack trace.

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
        -->
    <customErrors mode="Off"></customErrors>

    <pages>
      <controls>
        <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </controls>
    </pages>

    <httpHandlers>
      <remove verb="*" path="*.svc"/>
      <add verb="*" path="*.svc" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="false" />
      <remove verb="*" path="*.asmx"/>
      <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
    </httpHandlers>
    <httpModules>
      <remove name="ScriptModule" />
      <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <remove name="ServiceModel" />
      <add name="ServiceModel" type="System.ServiceModel.Activation.HttpModule, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
    </httpModules>

  </system.web>

  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4"
                type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <providerOption name="CompilerVersion" value="v3.5"/>
        <providerOption name="WarnAsError" value="false"/>
      </compiler>
    </compilers>
  </system.codedom>

  <system.web.extensions>
    <scripting>
      <webServices>
        <!--
              Uncomment this section to enable the authentication service. Include 
              requireSSL="true" if appropriate.

          <authenticationService enabled="true" requireSSL = "true|false"/>
          -->
        <!--
              Uncomment these lines to enable the profile service, and to choose the 
              profile properties that can be retrieved and modified in ASP.NET AJAX 
              applications.

          <profileService enabled="true"
                          readAccessProperties="propertyname1,propertyname2"
                          writeAccessProperties="propertyname1,propertyname2" />
          -->
        <!--
              Uncomment this section to enable the role service.

          <roleService enabled="true"/>
          -->
      </webServices>
      <!--
        <scriptResourceHandler enableCompression="true" enableCaching="true" />
        -->
    </scripting>
  </system.web.extensions>
  <!--
        The system.webServer section is required for running ASP.NET AJAX under Internet
        Information Services 7.0.  It is not necessary for previous version of IIS.
    -->
  <system.webServer>

    <validation validateIntegratedModeConfiguration="false"/>
    <modules>
      <remove name ="ScriptModule"/>
      <add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    </modules>
    <handlers>
      <remove name="WebServiceHandlerFactory-Integrated"/>
      <remove name ="ScriptHandlerFactory"/>
      <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode"
           type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <remove name="ScriptHandlerFactoryAppServices"/>
      <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode"
           type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <remove name="ScriptResource"/>
      <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    </handlers>
  </system.webServer>


  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttp">
          <security mode="None" />
        </binding>
      </wsHttpBinding>
    </bindings>

    <services>
      <service name="WcfWebService1.Service1" behaviorConfiguration="WcfWebService1.Service1Behavior">
        <!-- Service Endpoints -->
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttp" contract="WcfWebService1.IService1">
          <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          -->
          <identity>
            <dns value="http://mytestsubdomain.mydomain.com"/&gt;
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WcfWebService1.Service1Behavior">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- 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>
    </behaviors>





  </system.serviceModel>
</configuration>

Alright, so still getting the same issues. The SVC is very simple for now - just need to get this working on our host:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;              //all WCF subclasses
using System.ServiceModel.Activation;   // required for ServiceHostFactory
using System.Text;

namespace WcfWebService1
{
    // NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file.
    public class Service1 : IService1
    {
        public string GetUserName(long userID)
        {
            return (BLLData.Instance.GetUserName(userID));
        }


        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }

        // definde service contract

    }


    /// <summary>
    /// Custom factory added to work with medium trust environments
    /// and reference in the service's markup definition
    /// </summary>
    class CustomHostFactory : ServiceHostFactory
    {
        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            // If more than one base address exists then return the second address,
            // otherwise return the first address
            if (baseAddresses.Length > 1)
            {
                return new ServiceHost(serviceType, baseAddresses[1]);
            }
            else
            {
                return new ServiceHost(serviceType, baseAddresses[0]);
            }
        }
    }

    class CustomHost : ServiceHost
    {
        public CustomHost(Type serviceType, params Uri[] baseAddresses)
            : base(serviceType, baseAddresses)
        { }
    }
A: 

At first I thought the .svc handlers weren't loading. Locally I'm running IIS7 and to get IIS 7 web.config handlers working they're in a different location:

  <system.webServer>
    <handlers>
      <!-- handler for IIS 7 -->
      <add name=".svc" 
           verb="*" 
           path="*.svc"
           type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

That worked locally when navigating to my virtual directory in the browser, but still didn't work on the our host. Why? They're using IIS6. Ok, so that's not the solution.

Blankman's solution, found here http://stackoverflow.com/questions/451701/wcf-not-running-under-iis6-0 - did the trick.

Our site had multiple host headers and had to use a factory in my .svc.cs file to resolve this:

public class MultipleHostServiceFactory : ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        List<Uri> addresses = new List<Uri>();
        addresses.Add(baseAddresses[0]);
        return base.CreateServiceHost(serviceType, addresses.ToArray());
    }
}

And then set the factory markup:

<%@ ServiceHost Language="C#" 
                Debug="false" 
                Factory="MyNamespace.MultipleHostServiceFactory" 
                Service="MyNamespace.MyService" 
                CodeBehind="MyService.svc.cs" %>

Hope this helps someone.

ElHaix
A: 

I was able to get REST WCF up and running on my GoDaddy shared hosting. Since I spent so much time searching online and haven't find anything, I've written a post on my blog.

http://blog.infaloom.com/?p=57

Feel free to ask if you need any help.

Best

Jovica Zaric