简体   繁体   English

WCF和Silverlight之间的序列化

[英]Serialization between WCF and Silverlight

I need an expert's help. 我需要专家的帮助。 I have a custom class called MyException. 我有一个名为MyException的自定义类。 The purpose of this class is to log exceptions with custom information. 此类的目的是记录带有自定义信息的异常。 The definition of this class is as shown here: 此类的定义如下所示:

[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;
  }
}

I have a WCF service that is intended to accept a MyException in JSON format and write it's contents to a database. 我有一个WCF服务,该服务旨在接受JSON格式的MyException并将其内容写入数据库。 Because of the amount of information I intend to track, I need to use a POST operation, so I decided to base my implementation off this blog post . 由于我打算跟踪的信息量很大,因此我需要使用POST操作,因此我决定将实现基于此博客文章 My service description can be found here: 我的服务描述可以在这里找到:

[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)
{ }

I added the "Test" operation so that the MyException would be exposed during proxy generation to my Silverlight application. 我添加了“ Test”操作,以便在代理生成期间将MyException暴露给我的Silverlight应用程序。 My Silverlight application attempts to post to LogError using the following code: 我的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);
}

When I run this code, I get an error in my Silverlight app that says: "Type 'MyServiceProxy.MyException' with data contract name 'MyException:http://schemas.datacontract.org/2004/07/MyNamespace' is not expected. 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 DataContractSerializer." 当我运行此代码时,我的Silverlight应用程序中出现错误,提示:“不希望输入数据协定名称为“ MyException:http://schemas.datacontract.org/2004/07/MyNamespace”的“ MyServiceProxy.MyException”类型将任何静态未知的类型添加到已知类型的列表中,例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型的列表中。”

What am I doing wrong? 我究竟做错了什么?

You specify in the request that the content-type of the request is "application/x-www-form-urlencoded". 您在请求中指定请求的内容类型为“ application / x-www-form-urlencoded”。 But the content is actually JSON (generated using the DataContractJsonSerializer ). 但是内容实际上是JSON(使用DataContractJsonSerializer生成)。 Try updating the content-type to the correct one ("application/json") and that should get you further where you need to be. 尝试将内容类型更新为正确的内容类型(“ application / json”),这应该使您更进一步。

I believe the issue here is that your type is different, you are using the proxy class and serializing it, and then trying to deserialize it as a different type when you get it back on the server side. 我认为这里的问题是您的类型不同,您正在使用代理类并对其进行序列化,然后在将其返回服务器端时尝试将其反序列化为其他类型。

You should be able to add the KnownType attribute, I believe this would be needed on the auto generated proxy class. 您应该能够添加KnownType属性,我相信在自动生成的代理类上将需要此属性。

Maybe if you explicitly set the namespace on the DataContract attribute. 也许如果您在DataContract属性上显式设置名称空间。 Something like [DataContract(Namespace = "http://tempuri.org/2010/etc")] so the serializer would treat the classes as being the same. 类似于[DataContract(Namespace = "http://tempuri.org/2010/etc")]因此序列化程序会将类视为相同。

I would give it a try. 我会尝试的。 Adding the namespace and regenerating the reference. 添加名称空间并重新生成引用。

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

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