WCF 백엔드와 UWP 프런트 엔드가있는 C # 응용 프로그램이 있습니다. 내 서비스 계약을 구현하는 서비스가 있습니다. 서비스에서 예외를 포착하고이를 Fault Exceptions로 다시 던지면 모든 것이 예상대로 작동합니다.
이제 RealProxy 인스턴스를 사용하여 서비스 호출을 래핑하고 프록시에서 내 오류 예외를 발생시켜 서비스 코드를 정리하려고합니다. 불행히도 서비스에서 예외가 발생하면 클라이언트가 다음 메시지와 함께 예외를 수신합니다.
"서버가 의미있는 응답을 제공하지 않았습니다. 이는 계약 불일치, 조기 세션 종료 또는 내부 서버 오류로 인해 발생할 수 있습니다."
다음 서비스 계약이 있습니다.
[ServiceContract(Namespace = @"blah/blah/blah", SessionModel = SessionMode.Required)
public interface IService1
{
[OperationContract]
[FaultContract(typeof(Exception))]
bool DoSomething(Setting setting);
}
다음 구현으로 :
[Export(typeof(IService1)]
[ServiceBehavior(InstanceContextMode = IntanceContextMode.Single,
ConcurrencyMode = ConcurrencyModel.Single]
public class Service1 : IService1
{
bool DoSomthing(Setting setting)
{
try
{
throw new ArgumentException("setting");
}
catch (Exception ex)
{
throw WrapException(ex);
}
}
private FaultException<Exception> WrapException(Exception ex)
{
string message = exception.GetBaseException().Message;
Console.WriteLine(string.Format("Exception: {0}", message));
return new FaultException<Exception>(exception, new FaultReason(message));
}
}
내 WCF 서비스 호스트에는 클라이언트 측의 해당 구성과 함께 다음 구성이 있습니다.
<system.serviceModel>
<services>
<service name="Host.Services.Service1">
<endpoint address="net.tcp://localhost:8082/Service1"
binding="netTcpBinding"
contract="Host.Domain.IService1"/>
</service>
</services>
<bindings>
<netTcpBinding>
<binding maxReceivedMessageSize="1000000">
<security mode="None"></security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
이제 프록시를 만들었습니다.
public class ServiceProxy<T> : RealProxy
{
private readonly T _instance;
private ServiceProxy(T instance)
: base(typeof(T))
{
_instance = instance;
}
public static T Create(T instance)
{
return (T) new ServiceProxy<T>(instance).GetTransparentProxy();
}
public override IMessage Invoke(IMessage msg)
{
var methodCall = (IMethodCallMessage) msg;
var method = (MethodInfo) methodCall.MethodBase;
try
{
var result = method.Invoke(_instance, methodCall.InArgs);
return new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall);
}
catch (Exception ex)
{
string message = ex.GetBaseException().Message;
Console.WriteLine(string.Format("Exception: {0}", message));
var wrapped = new FaultException<Exception>(ex, new FaultReason(message));
return new ReturnMessage(wrapped, msg as IMethodCallMessage);
}
}
}
(아이디어에 대해 @bradmo에게 감사드립니다.)
프록시를 내 서비스로 사용하고 있습니다.
static void Main(string[] args)
{
try
{
var service = new Bootstrapper().Run().GetExport<IService1>().Value;
IService1 proxy = ServiceProxy<IService1>.Create(service);
using (var host = new ServiceHost(proxy))
{
host.Open();
Console.WriteLine("Running...");
Console.ReadLine();
}
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Exception: {0}", ex.GetBaseException().Message));
Console.ReadLine();
}
}
}
프록시없이 오류 예외를 던지면 제대로 작동하고 예외가없는 경우 프록시가 제대로 작동하지만 프록시를 사용하여 예외를 래핑하면 클라이언트 측에서 다음 오류가 발생합니다.
"서버가 의미있는 응답을 제공하지 않았습니다. 이는 계약 불일치, 조기 세션 종료 또는 내부 서버 오류로 인해 발생할 수 있습니다."
문제는 FaultContract가 정의 된 방식에있는 것 같습니다.
이 라인을 따라 무언가를 시도하고 도움이되는지 확인하십시오.
public interface IService
{
[OperationContract]
[FaultContract(typeof(WrappedExceptionFault))]
bool DoSomething(string setting);
}
[DataContract]
public class WrappedExceptionFault
{
[DataMember]
public string Message { get; set; }
}
public class Service : IService
{
public bool DoSomething(string setting)
{
try
{
throw new ArgumentException(setting);
}
catch (Exception ex)
{
throw WrapException(ex);
}
}
private FaultException<WrappedExceptionFault> WrapException(Exception ex)
{
string message = ex.GetBaseException().Message;
Console.WriteLine(string.Format("Exception: {0}", message));
WrappedExceptionFault fault = new WrappedExceptionFault()
{
Message = message,
};
return new FaultException<WrappedExceptionFault>(fault, new FaultReason(message));
}
}
또한 : 'using'절에 serviceHost를 래핑해서는 안됩니다. .. 큰 문제를 요청하는 것입니다. 다음과 같은 작업을 고려하십시오.
ServiceHost host = new ServiceHost(proxy);
host.Open();
Console.WriteLine("Running...");
Console.ReadLine();
try
{
host.Close();
}
catch
{
host.Abort();
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다