1

Ok, so..

I have a WCF service that throws a WebFaultException<Error>(Error, HttpStatusCode.BadRequest) where Error is my custom, serializable object.

This all works as expected when I host the service on my local machine, and on GoDaddy's (as seen here: link removed). But when hosted with Arvixe all I receive is a 'Bad Request' response (as seen here: link removed)

Analyzing the response headers, it appears that my local machine, GoDaddy, and Arvixe are all using the same .NET version. However, my local machine is running IIS 8.0, GoDaddy is running IIS 7.0, and Arvixe is running IIS 8.5.

So, what's causing the discrepancy? Does IIS 8.5 handle WebFaultException's differently? Nothing I find on the internet suggests it does. Or does IIS need to be configured to return WebFaultExceptions? Again, everything I read says it is configured entirely in the ASP Web.config.

Any other suggestions?

** EDIT **

I'm fairly certain this has to do with IIS and not my code, considering it works fine on my local machine (IIS8) and GoDaddy (IIS7), but not on Arvixe (IIS8.5)

Anyways, here's some snippets:

The error object I'm trying to return

    [DataContract]
public class Error {

    [DataMember]
    public int Code { get; set; }

    [DataMember]
    public string Message { get; set; }

    [DataMember]
    public string Display { get; set; }

    [DataMember]
    public List<Error> Details { get; set; }

    public Error(int code, string message, List<Error> details = null, string display = null) {
        this.Code = code;
        this.Message = message;
        this.Display = display;
        this.Details = details ?? new List<Error>();
    }
}

Trying to return it to the client via:

throw new WebFaultException<Error>(new Error(802, "games/asdf"), HttpStatusCode.BadRequest);

The method I am trying to throw the WebFaultException from:

    [OperationContract]
    [WebInvoke(
        Method = "GET", 
        UriTemplate = "/games/{game}/scores"
    )]
    List<Score> GetScores(string game);

I have tried adding a [FaultContract(typeof(Error))] attribute to the method but it had no effect.

Here's the Web.config registering my service

<?xml version="1.0"?>
<configuration>

<appSettings>
</appSettings>

<connectionStrings>
  <!-- DEV -->
  <add name="App" connectionString="XXX" />
  <add name="Log" connectionString="XXX" />
</connectionStrings>  

<system.web>

  <compilation debug="true" targetFramework="4.5" />
  <httpRuntime targetFramework="4.5" />

  <webServices>
    <protocols>
      <clear />
      <add name="HttpGet"/>
      <add name="HttpPost" />
      <add name="HttpPostLocalhost" />
    </protocols>
  </webServices>

  <pages>
    <namespaces>
      <add namespace="System.Web.Optimization" />
    </namespaces>
  </pages>

</system.web>

<system.serviceModel>

  <behaviors>

    <serviceBehaviors>

    <!--old-->
    <behavior name="OldService">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>

    <!--new-->
    <behavior name="V3">
      <serviceAuthorization serviceAuthorizationManagerType="ScoresWs.V3.Auth, ScoresWs"/>
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />          
    </behavior>

  </serviceBehaviors>

  <endpointBehaviors>
    <behavior name="REST">
      <!--faultExceptionEnabled needs to be false or else we return .net exceptions as xml instead of our custom WebFaultException-->
      <webHttp 
        helpEnabled="true"
        faultExceptionEnabled="false" 
        automaticFormatSelectionEnabled="false" 
        defaultOutgoingResponseFormat="Json" />
    </behavior>
  </endpointBehaviors>

</behaviors>

<bindings>
  <webHttpBinding>
    <binding name="defaultBinding" maxReceivedMessageSize="2097152">
      <security mode="None" />
    </binding>
  </webHttpBinding>
</bindings>

<services>

  <service name="ScoresWs.WebServiceV2" behaviorConfiguration="OldService">
    <endpoint 
      address="" 
      binding="webHttpBinding" 
      behaviorConfiguration="REST" 
      bindingConfiguration="defaultBinding" 
      contract="ScoresWs.IWebServiceV2" />
  </service>

  <service name="ScoresWs.V3.Api" behaviorConfiguration="V3">
    <endpoint
      address=""
      binding="webHttpBinding"
      behaviorConfiguration="REST"
      bindingConfiguration="defaultBinding"
      contract="ScoresWs.V3.IApi"/>
  </service>

</services>

<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

</system.serviceModel>

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true" />
  <directoryBrowse enabled="false" />
</system.webServer>

<runtime>

  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31ad335" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
        </dependentAssembly>
      </assemblyBinding>

  </runtime>  

</configuration>

Annnnnnd lastly I activate the webservices in my Global.asax:

    public class Global : System.Web.HttpApplication {

      protected void Application_Start(object sender, EventArgs e) {
        RouteTable.Routes.Add(new ServiceRoute("api/v2", new WebServiceHostFactory(), typeof(ScoresWs.WebServiceV2)));
        RouteTable.Routes.Add(new ServiceRoute("api/v3", new WebServiceHostFactory(), typeof(ScoresWs.V3.Api)));
      }

    }
Cailen
  • 630
  • 1
  • 9
  • 23
  • Could be related to svc handler mapping (IIS 8.x) http://stackoverflow.com/questions/11116134/wcf-on-iis8-svc-handler-mapping-doesnt-work – Carl Prothman May 23 '15 at 16:44
  • Hmmm.. That seems to be a different issue. My service IS running correctly, it just won't return custom WebFaultException details when I throw them for bad requests (valid requests return a json response correctly). – Cailen May 23 '15 at 17:36
  • Show some sample code which repros the issue? – Carl Prothman May 23 '15 at 17:38

1 Answers1

0

Solved it! Like I suspected, it had nothing to do with my code.

In the Arvixe hosting panel I had to enabled "Show detailed ASP.NET errors in browser" (WebSites->Errors->ASP.NET). However, I'm not exactly sure what impact this has on security, since the Web.config hasn't changed and I can't see the IIS configuration.

Odd that the Arvixe support team wouldn't have directed me here immediately considering 'my detailed ASP.NET errors' weren't being sent to the client.

Cailen
  • 630
  • 1
  • 9
  • 23