繁体   English   中英

WCF和Silverlight之间的序列化

[英]Serialization between WCF and Silverlight

我需要专家的帮助。 我有一个名为MyException的自定义类。 此类的目的是记录带有自定义信息的异常。 此类的定义如下所示:

[DataContract]
public class MyException
{
  [DataMember]
  public string StackTrace { get; set; }

  [DataMember]
  public string Message { get; set; }

  [DataMember]
  public string Component { get; set; }

  [DataMember]
  public string TypeName { get; set; }

  [DataMember]
  public string Miscellaneous { get; set; }

  public MyException() 
  {}

  public MyException(string message)
  {
    this.Message = message;
  }

  public MyException(string message, string stackTrace)
  {
    this.Message = message;
    this.StackTrace = stackTrace;
  }
}

我有一个WCF服务,该服务旨在接受JSON格式的MyException并将其内容写入数据库。 由于我打算跟踪的信息量很大,因此我需要使用POST操作,因此我决定将实现基于此博客文章 我的服务描述可以在这里找到:

[OperationContract]
[WebInvoke(UriTemplate="/LogError", Method="POST", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public string LogError(Stream stream)
{
  try
  {
    DataContractJsonSerializer serializer = 
      new DataContractJsonSerializer(typeof(MyException));
    MyException exception = (MyException)(serializer.ReadObject(stream));
    // Write the exception details to the database
  }
  catch (Exception ex)
  {
    // Write the exception details to the database
  }
}

[OperationContract]
public void Test(MyException exception)
{ }

我添加了“ Test”操作,以便在代理生成期间将MyException暴露给我的Silverlight应用程序。 我的Silverlight应用程序尝试使用以下代码发布到LogError:

MyServiceProxy.MyException exception = new MyServiceProxy.MyException();
exception.Message = e.Error.Message;
exception.StackTrace = e.Error.StackTrace;
exception.Component = GetComponentName();
exception.TypeName = e.Error.FullName;

string json = string.Empty;
using (MemoryStream stream = new MemoryStream())
{
  DataContractJsonSerializer serializer = new 
    DataContractJsonSerializer(typeof(MyServiceProxy.MyException));
  serializer.WriteObject(stream, exception);

  stream.Position = 0;
  using (StreamReader reader = new StreamReader(stream))
  {
    json = reader.ReadToEnd();
  }

  Uri uri = new Uri("/myService.svc/LogError", UriKind.Absolute);
  WebClient myService = new WebClient();
  myService.UploadStringCompleted += 
    new UploadStringCompletedEventHandler(myService_UploadStringCompleted);
  myService.Headers["Content-type"] = "application/x-www-form-urlencoded";
  myService.Encoding = Encoding.UTF8;
  myService.UploadStringAsync(uri, "POST", json);
}

当我运行此代码时,我的Silverlight应用程序中出现错误,提示:“不希望输入数据协定名称为“ MyException:http://schemas.datacontract.org/2004/07/MyNamespace”的“ MyServiceProxy.MyException”类型将任何静态未知的类型添加到已知类型的列表中,例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型的列表中。”

我究竟做错了什么?

您在请求中指定请求的内容类型为“ application / x-www-form-urlencoded”。 但是内容实际上是JSON(使用DataContractJsonSerializer生成)。 尝试将内容类型更新为正确的内容类型(“ application / json”),这应该使您更进一步。

我认为这里的问题是您的类型不同,您正在使用代理类并对其进行序列化,然后在将其返回服务器端时尝试将其反序列化为其他类型。

您应该能够添加KnownType属性,我相信在自动生成的代理类上将需要此属性。

也许如果您在DataContract属性上显式设置名称空间。 类似于[DataContract(Namespace = "http://tempuri.org/2010/etc")]因此序列化程序会将类视为相同。

我会尝试的。 添加名称空间并重新生成引用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM