我试图将自定义异常从WCF服务抛出到客户端应用程序。我将尝试描述尽可能多的代码,因为我认为可以与此相关。
例外:
using System.Runtime.Serialization;
namespace App.Exceptions
{
/// <summary>
/// General App exception
/// </summary>
[DataContract]
public class AppException : System.Exception
{
private string strMessage = "An unknown exception occurred";
/// <summary>
/// Creates a new instance of a App Exception
/// </summary>
public AppException()
{ }
/// <summary>
/// Creates a new instance of a App Exception
/// </summary>
/// <param name="Message">Message to send as exception</param>
public AppException(string Message)
{ strMessage = Message; }
public override string Message
{ get { return strMessage; } }
}
}
服务代码:
(...)
using App.Exceptions;
namespace App.Services
{
public class Service1 : IService1
{
public Service1 ()
{ }
public void TestFunction()
{
throw new AppException();
}
}
}
serviceInterface等:
(...)
namespace App.Services.Interfaces
{
[ServiceContract]
public interface IService1
{
[OperationContract]
void TestFunction();
}
}
客户端:
(...)
using App.Exceptions;
(...)
try
{
service.TestFunction();
}
catch (AppException ex)
{
}
一切运行良好,在服务上调用函数并抛出异常。客户端和服务器上的引用完全相同。我已经在同一个名字上引用了AppException
,所以它应该没问题。
我已经尝试过服务app.config
来设置<serviceDebug includeExceptionDetailInFaults="True" />
并将其设置为False只是为了看看我是否得到了不同的例外情况,事实上它是不同的所以我是&#39; m没有真正理解为什么AppException
的捕获点上设置的断点从未被击中。
修改
服务配置:
<service name="App.Services.Service1">
<endpoint address="" binding="basicHttpBinding" contract="App.Services.Interfaces.IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/Design_Time_Addresses/App.Services/Service1/" />
</baseAddresses>
</host>
</service>
客户端配置:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8733/Design_Time_Addresses/App.Services/Service1/"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1"
contract="Services.IService1" name="BasicHttpBinding_IService1" />
</client>
</system.serviceModel>
答案 0 :(得分:0)
由于安全性和互操作性的原因,您不能将任何未处理的异常或.net或任何类似的异常从服务器抛出到客户端(如果客户端想要知道激活),默认情况下这些异常不会传播到客户端wcf服务。
WCF不是传播异常,而是将它们序列化为SOAP错误并将SOAP错误发送到客户端。因此,您需要在SOAP错误中包含此自定义异常。
首先让servicecontract知道哪个操作可以抛出哪些SOAP错误。
namespace App.Services.Interfaces
{
[ServiceContract]
public interface IService1
{
[FaultContract(typeOf(AppException))]
[OperationContract]
void TestFunction();
}
}
using System.ServiceModel;
public class Service1 : IService1
{
public Service1 ()
{ }
public void TestFunction()
{
try
{
service.TestFunction();
}
catch(Exception ex)
{
AppException app=new AppException();
app.strMessage =ex.Message;
throw new FaultExcpetion<AppException>(app);
}
}
}
此外,您可以获得故障详细信息以及故障错误。在客户端捕获上述异常。
//client side
try
{
//call wcf service contract.
}
catch (FaultException<ServiceReference.AppException> ex)
{
label.Text=ex.Detail.strMessage ;
}
另一种方法是使用自定义WCF IErrorHandler实现。请参阅此https://stackoverflow.com/a/8764782/6086968以便集中处理异常。
Edit1:需要为元数据正确配置app.config。
<service name="App.Services.Service1" behaviorConfiguration="mexendpoint">
<endpoint address="" binding="basicHttpBinding" contract="App.Services.Interfaces.IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/Design_Time_Addresses/App.Services/Service1/" />
</baseAddresses>
</host>
</service>
<behaviors>
<serviceBehaviors>
<behavior name="mexendpoint">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>