c# - 序列化一个通用类型的 FaultException

标签 c# asp.net web-services wcf faultexception

我们目前有一种在测试页面中调用网络服务的机制。但是,我正在尝试查看 WCF 服务的更好做法并使用 FaultException。

所以有我们服务抛出FaultException的情况,我想将该故障序列化为xml显示在页面上。

到目前为止,我已经查看了 XmlSerializerDataContractSerializer

所以考虑代码:

public SomeResponse DoSomething()
{
    throw new FaultException<AuthenticationFault>(
                new AuthenticationFault(), 
                new FaultReason("BooHoo"), 
                new FaultCode("1234"));
}

以及徒劳的序列化尝试:

DataContractSerializer

public static string Serialize(object obj)
{
    using (MemoryStream memoryStream = new MemoryStream())
    using (StreamReader reader = new StreamReader(memoryStream))
    {
        DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
        serializer.WriteObject(memoryStream, obj);
        memoryStream.Position = 0;
        return reader.ReadToEnd();
    }
}

XmlSerializer

public string Serialize<TObject>(TObject obj)
{
    if (obj == null)
    {
        return string.Empty;
    }

    XmlSerializer serializer = new XmlSerializer(obj.GetType());
    XmlWriterSettings settings = new XmlWriterSettings()
    {
        Encoding = new UnicodeEncoding(false, false), string
        Indent = true,
        OmitXmlDeclaration = true
    };

    using (StringWriter textWriter = new StringWriter())
    {
        using (XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings))
        {
            serializer.Serialize(xmlWriter, obj);
        }
        return textWriter.ToString();
    }
}

测试调用和接听

public override string Invoke(string request)
{
    try
    {
        var service = new AcmeService();
        return Serialize(service.DoSomething());
    }
    catch (FaultException ex)
    {
        return Serialize(ex);
    }
}

认证错误

[DataContract]
public class AuthenticationFault
{
}

异常(exception)情况

在上述场景中会引发以下异常。但是,我很欣赏通用 FaultException 没有无参数构造函数。运行时必须能够通过线路重新序列化。

DataContractSerializer

System.Runtime.Serialization.SerializationException occurred
  HResult=0x8013150C
  Message=Type 'BuyerAcmeApp.Services.Faults.AuthenticationFault' with data contract name 'AuthenticationFault:http://schemas.acme.com/p4/services/2017/11' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.
  Source=<Cannot evaluate the exception source>
  StackTrace:
<Cannot evaluate the exception stack trace>

XmlSerializer

System.InvalidOperationException occurred
  HResult=0x80131509
  Message=There was an error reflecting type 'System.ServiceModel.FaultException'.
  Source=App_Code.etbsvkgf
  StackTrace:
   at AcmeApp.WebServices.Tests.WebServiceMethodItem`2.Serialize[TObject](TObject obj) in T:\acmejpa\AcmeAppTemplate\dev\solution\AcmeApp.Template\src\AcmeApp\App_Code\WebServices\Tests\WebServiceMethodItemBase.cs:line 70
   at AcmeApp.WebServices.Tests.WebServiceMethodItemWithError`2.Invoke(String request) in T:\acmejpa\AcmeAppTemplate\dev\solution\AcmeApp.Template\src\AcmeApp\App_Code\WebServices\Tests\WebServiceMethodItemBase.cs:line 104
   at AcmeApp.Diagnostics.WebServiceTestPage.CallMethodButton_OnClick(Object sender, EventArgs e) in T:\acmejpa\AcmeAppTemplate\dev\solution\AcmeApp.Template\src\AcmeApp\Diagnostics\WebServiceTestPage.aspx.cs:line 44

Inner Exception 1:
NotSupportedException: Cannot serialize member System.Exception.Data of type System.Collections.IDictionary, because it implements IDictionary.

最佳答案

序列化时,需要将已知类型提供给 DataContractSerializer

public static string Serialize(object obj)
{
    var settings = new XmlWriterSettings { Indent = true };

    using (MemoryStream memoryStream = new MemoryStream())
    using (StreamReader reader = new StreamReader(memoryStream))
    {
        DataContractSerializer serializer = new DataContractSerializer(
        obj.GetType(), new Type[]
        {
            typeof(AuthenticationFault)
        });

        serializer.WriteObject(memoryStream , obj);
        memoryStream.Position = 0;
        return reader.ReadToEnd();
    }
}

关于c# - 序列化一个通用类型的 FaultException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47291522/

相关文章:

c# - 无法更改 DataGridViewComboBox 值

c# - 多用户 MS Access 数据库-如何完全锁定

c# - Blazor 中的数据绑定(bind) : How to propagate values out of a component?

c# - 当前上下文中不存在名称

asp.net - 如何设置禁用的 ASP.NET 按钮的样式

c# - 属性不适用于模型 ASP.NET MVC 5

c# - "sample"在探查器中代表多少秒?

java - JSR 跨域验证

适用于 Android 的 Java REST 客户端 API

web-services - 如何调用部署在VPS中的web服务