【发布时间】:2015-05-23 14:24:50
【问题描述】:
好的,所以..
我有一个 WCF 服务抛出WebFaultException<Error>(Error, HttpStatusCode.BadRequest),其中Error 是我的自定义、可序列化对象。
当我在本地机器和 GoDaddy 上托管服务时,这一切都按预期工作(如下所示:链接已删除)。 但是当使用 Arvixe 托管时,我收到的只是“错误请求”响应(如下所示:链接已删除)
分析响应标头,我的本地机器 GoDaddy 和 Arvixe 似乎都使用相同的 .NET 版本。但是,我的本地机器运行的是 IIS 8.0,GoDaddy 运行的是 IIS 7.0,而 Arvixe 运行的是 IIS 8.5。
那么,造成这种差异的原因是什么? IIS 8.5 处理 WebFaultException 的方式不同吗?我在互联网上找到的任何东西都没有表明它确实如此。或者是否需要将 IIS 配置为返回 WebFaultExceptions?同样,我读到的所有内容都说它完全在 ASP Web.config 中配置。
还有其他建议吗?
** 编辑 **
我相当肯定这与 IIS 而非我的代码有关,考虑到它在我的本地计算机 (IIS8) 和 GoDaddy (IIS7) 上运行良好,但在 Arvixe (IIS8.5) 上运行良好
无论如何,这里有一些 sn-ps:
我试图返回的错误对象
[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>();
}
}
尝试通过以下方式将其返回给客户端:
throw new WebFaultException<Error>(new Error(802, "games/asdf"), HttpStatusCode.BadRequest);
我试图从以下位置抛出WebFaultException 的方法:
[OperationContract]
[WebInvoke(
Method = "GET",
UriTemplate = "/games/{game}/scores"
)]
List<Score> GetScores(string game);
我尝试在方法中添加[FaultContract(typeof(Error))] 属性,但没有效果。
这是注册我的服务的 Web.config
<?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>
最后我激活了 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)));
}
}
【问题讨论】:
-
可能与 svc 处理程序映射 (IIS 8.x) stackoverflow.com/questions/11116134/… 有关
-
嗯.. 这似乎是一个不同的问题。我的服务运行正常,当我将它们抛出错误请求时,它不会返回自定义 WebFaultException 详细信息(有效请求正确返回 json 响应)。
-
显示一些重现问题的示例代码?