如何从WCF客户端向服务器发送托管异常(用于日志记录)?

InteXX

我正在尝试为WCF客户端应用程序构建错误日志记录机制,以便它们可以将WCF上下文外部可能发生的任何异常报告回服务。

在这种情况下,我绝对保证所有客户端都是.NET。

我发现了大量有关如何配置其他方式(例如,为客户提供服务)的信息,文章和示例,但对于客户提供的服务却一无所获。

我希望在客户端上执行以下操作:

Dim i As Integer

Try
  i = String.Empty

Catch ex As Exception
  Client.Create.Call(Sub(S As IService)
                       S.Log(LogLevels.Error, ex)
                     End Sub)

End Try

FaultException(Of T)不起作用;我尝试了这个:

Dim i As Integer

Try
  i = String.Empty

Catch ex As Exception
  Try
    Throw New FaultException(Of Exception)(ex)

  Catch fex As FaultException
    Client.Create.Call(Sub(S As IService)
                         S.Log(LogLevels.Error, fex.Message, fex)
                       End Sub)

  End Try
End Try

它返回自己的一个难以理解的错误消息:

不希望使用数据协定名称为'InvalidCastException的'类型'System.InvalidCastException':http : //schemas.datacontract.org/2004/07/System '。请考虑使用DataContractResolver或将任何静态未知的类型添加到已知列表中类型-例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中。”

异常的二进制序列化也不起作用。反序列化时出现错误:

“输入流不是有效的二进制格式。”

我的代码:

Class Test
  Public Sub Test
    Dim i As Integer
    Dim aEx As Byte()
    Dim oEx As Exception

    Try
      i = String.Empty

    Catch ex As Exception
      aEx = ex.ToBytes
      oEx = aEx.ToObject(Of Exception)()

    End Try
  End Sub
End Class

Public Module Generic
  <Extension>
  Public Function ToBytes(Of T)([Object] As T) As Byte()
    Using oStream As New MemoryStream
      With New BinaryFormatter
        .Serialize(oStream, [Object])
      End With

      Return oStream.ToArray
    End Using
  End Function



  <Extension>
  Public Function ToObject(Of T)(Data As Byte()) As T
    Using oStream As New MemoryStream
      oStream.Write(Data, 0, Data.Length)
      oStream.Seek(0, SeekOrigin.Begin)

      With New BinaryFormatter
        Return .Deserialize(oStream)
      End With
    End Using
  End Function
End Module

如何通过网络发送此非WCF异常?

编辑

这是我的服务界面,为简洁起见进行了编辑:

<ServiceContract>
Public Interface IService
  <OperationContract> Sub Log(Level As LogLevels, Message As String, Exception As Exception)
End Interface
InteXX

好吧,那是一个半程。希望我带来一些TrailMix。

解决方案原来是Microsoft的红发继子,在此NetDataContractSerializer简要提及您可以在这里阅读有关我为何称其为“为什么”的信息

Ron Jacobs帖子的底部(到Aaron Skonnard的帖子)有一个重要链接,该链接现已过期。我在这里找到了一个副本(评论很重要,请看一下)。看来蒂姆·斯科特(Tim Scott)也使用了亚伦(Aaron)的代码。

正是在蒂姆更彻底的解释中,我找到了圣杯。(我一直想这样做!)

Tim正在使用Attribute装饰,但是仅当在服务器上使用CLR对象时,这些装饰才适用在这种情况下,我们正在为客户工作

因此,最终,此修复程序简单易用。只需使用NetDataContractSerializer将打包System.ExceptionByte(),将数据发送到服务器,然后在其中反序列化即可。无需高呼,不需要硝烟的镜子,只需一眼即可。

这会降低性能,因此请尽量减少Exception

这是我最终得到的结果,然后是蒂姆针对可能需要它的任何人的代码:

System.Exception从客户端发送到服务器

Public Class Client
  Private Sub ClientTest()
    Dim i As Integer

    Try
      i = String.Empty

    Catch ex As Exception
      Client.Create.Call(Sub(S As IService)
                           S.Log(LogLevels.Error, ex.Message, ex.ToBytes)
                         End Sub)
    End Try
  End Sub
End Class



<ServiceContract>
Public Interface IService
  <OperationContract> Sub Log(Level As LogLevels, Message As String, Data As Byte())
End Interface



Public Class Service
  Implements IService

  Public Sub Log(Level As LogLevels, Message As String, Data As Byte()) Implements IService.Log
    ' Log4Net logger created separately, out of scope of this question '
    Select Case Level
      Case LogLevels.Debug : Main.Logger.Debug(Message, Data.ToException)
      Case LogLevels.Info : Main.Logger.Info(Message, Data.ToException)
      Case LogLevels.Warn : Main.Logger.Warn(Message, Data.ToException)
      Case LogLevels.Error : Main.Logger.Error(Message, Data.ToException)
      Case LogLevels.Fatal : Main.Logger.Fatal(Message, Data.ToException)
    End Select
  End Sub
End Class



Public Module Extensions
  <Extension>
  Public Function ToBytes(Instance As Exception) As Byte()
    Using oStream As New MemoryStream()
      With New NetDataContractSerializer
        .Serialize(oStream, Instance)
      End With

      Return oStream.ToArray
    End Using
  End Function



  <Extension>
  Public Function ToException(Data As Byte()) As Exception
    Using oStream As New MemoryStream(Data)
      With New NetDataContractSerializer
        Return .Deserialize(oStream)
      End With
    End Using
  End Function
End Module

将CLR对象(包括泛型)发送给客户端

public class NetDataContractOperationBehavior : DataContractSerializerOperationBehavior
{
    public NetDataContractOperationBehavior(OperationDescription operation)
        : base(operation)
    {
    }   

    public NetDataContractOperationBehavior(OperationDescription operation, DataContractFormatAttribute dataContractFormatAttribute)
        : base(operation, dataContractFormatAttribute)
    {
    }   

    public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns,
        IList<Type> knownTypes)
    {
        return new NetDataContractSerializer(name, ns);
    }   

    public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name,
        XmlDictionaryString ns, IList<Type> knownTypes)
    {
        return new NetDataContractSerializer(name, ns);
    }
}   



public class UseNetDataContractSerializerAttribute : Attribute, IOperationBehavior
{
    public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
    {
    }   

    public void ApplyClientBehavior(OperationDescription description,
        System.ServiceModel.Dispatcher.ClientOperation proxy)
    {
        ReplaceDataContractSerializerOperationBehavior(description);
    }   

    public void ApplyDispatchBehavior(OperationDescription description,
        System.ServiceModel.Dispatcher.DispatchOperation dispatch)
    {
        ReplaceDataContractSerializerOperationBehavior(description);
    }   

    public void Validate(OperationDescription description)
    {
    }   

    private static void ReplaceDataContractSerializerOperationBehavior( OperationDescription description)
    {
        DataContractSerializerOperationBehavior dcsOperationBehavior =
        description.Behaviors.Find<DataContractSerializerOperationBehavior>();   

        if (dcsOperationBehavior != null)
        {
            description.Behaviors.Remove(dcsOperationBehavior);
            description.Behaviors.Add(new NetDataContractOperationBehavior(description));
        }
    }
}


// Then in the service contract, to every method we added the UseNetDataContractSerializer attribute, like so:
[UseNetDataContractSerializer]
[OperationContractAttribute]
Company SaveCompany(CompanyUpdater companyUpdater);

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

从服务器向客户端发送哈希映射时的Java Null指针异常

来自分类Dev

如何抑制冒泡到客户端的EJBException的服务器端日志记录?

来自分类Dev

从服务器向客户端发送数据

来自分类Dev

服务器无法向客户端发送消息

来自分类Dev

服务器向客户端发送消息

来自分类Dev

向/从客户端/服务器发送对象

来自分类Dev

服务器向客户端发送消息

来自分类Dev

从服务器向 websocket 客户端发送消息

来自分类Dev

如何理解客户端在服务器中向哪个路由发送了Websocket消息?

来自分类Dev

Spring Integration和TCP服务器套接字-如何向客户端发送消息?

来自分类Dev

如何使服务器在单击按钮时向客户端发送消息

来自分类Dev

如何从服务器向客户端发送消息(TCP,Android应用程序)

来自分类Dev

如何使用Java RMI从服务器向客户端发送消息?

来自分类Dev

如何从节点js服务器向客户端发送json数据?

来自分类Dev

如何使用端口从服务器向客户端发送消息?

来自分类Dev

如何从Qt中的服务器向连接的客户端发送消息

来自分类Dev

如何从 Python 服务器向 Java 客户端发送消息

来自分类Dev

在服务器事件中从服务器向客户端发送通知

来自分类Dev

Signalr从服务器向客户端发送消息c#执行请求时发生未处理的异常

来自分类Dev

从客户端向服务器发送JSON字符串时出现400错误的请求异常

来自分类Dev

c#通过WCF从客户端向服务器端传递arraylist

来自分类Dev

如何从客户端桌面应用程序向服务器端Spring应用程序发送请求?

来自分类Dev

Angularjs | 如何记录客户端错误并将其发送到服务器端?

来自分类Dev

WCF服务返回“不良”响应-客户端获得的数据与服务器发送的数据不同

来自分类Dev

从服务器端向客户端发送jwt令牌的正确方法是什么?

来自分类Dev

如何在客户端服务器程序中集成log4j日志记录?

来自分类Dev

自托管的开源Web客户端,用于自己的邮件和日历服务器

来自分类Dev

如何在onc-rpc中从服务器向客户端发送字符串(char *)

来自分类Dev

运行龙卷风服务器时,如何每隔X秒向客户端发送消息?

Related 相关文章

  1. 1

    从服务器向客户端发送哈希映射时的Java Null指针异常

  2. 2

    如何抑制冒泡到客户端的EJBException的服务器端日志记录?

  3. 3

    从服务器向客户端发送数据

  4. 4

    服务器无法向客户端发送消息

  5. 5

    服务器向客户端发送消息

  6. 6

    向/从客户端/服务器发送对象

  7. 7

    服务器向客户端发送消息

  8. 8

    从服务器向 websocket 客户端发送消息

  9. 9

    如何理解客户端在服务器中向哪个路由发送了Websocket消息?

  10. 10

    Spring Integration和TCP服务器套接字-如何向客户端发送消息?

  11. 11

    如何使服务器在单击按钮时向客户端发送消息

  12. 12

    如何从服务器向客户端发送消息(TCP,Android应用程序)

  13. 13

    如何使用Java RMI从服务器向客户端发送消息?

  14. 14

    如何从节点js服务器向客户端发送json数据?

  15. 15

    如何使用端口从服务器向客户端发送消息?

  16. 16

    如何从Qt中的服务器向连接的客户端发送消息

  17. 17

    如何从 Python 服务器向 Java 客户端发送消息

  18. 18

    在服务器事件中从服务器向客户端发送通知

  19. 19

    Signalr从服务器向客户端发送消息c#执行请求时发生未处理的异常

  20. 20

    从客户端向服务器发送JSON字符串时出现400错误的请求异常

  21. 21

    c#通过WCF从客户端向服务器端传递arraylist

  22. 22

    如何从客户端桌面应用程序向服务器端Spring应用程序发送请求?

  23. 23

    Angularjs | 如何记录客户端错误并将其发送到服务器端?

  24. 24

    WCF服务返回“不良”响应-客户端获得的数据与服务器发送的数据不同

  25. 25

    从服务器端向客户端发送jwt令牌的正确方法是什么?

  26. 26

    如何在客户端服务器程序中集成log4j日志记录?

  27. 27

    自托管的开源Web客户端,用于自己的邮件和日历服务器

  28. 28

    如何在onc-rpc中从服务器向客户端发送字符串(char *)

  29. 29

    运行龙卷风服务器时,如何每隔X秒向客户端发送消息?

热门标签

归档