Сериализация между WCF и Silverlight - PullRequest
1 голос
/ 08 февраля 2011

Мне нужна помощь эксперта.У меня есть собственный класс под названием 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, которая предназначена для приема MyException в формате JSON и записи его содержимого в базу данных.Из-за объема информации, которую я собираюсь отслеживать, мне нужно использовать операцию 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)
{ }

Я добавил операцию «Тест», чтобы исключение 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 появляется сообщение об ошибке: «Введите« MyServiceProxy.MyException »с именем контракта данных«MyException: http://schemas.datacontract.org/2004/07/MyNamespace' не ожидается. Добавьте любые типы, которые не известны статически, в список известных типов - например, с помощью атрибута KnownTypeAttribute или добавив их в список известных типов, передаваемых в DataContractSerializer."

Что я делаю не так?

Ответы [ 3 ]

0 голосов
/ 15 марта 2011

Может быть, если вы явно установите пространство имен в атрибуте DataContract. Что-то вроде [DataContract(Namespace = "http://tempuri.org/2010/etc")], поэтому сериализатор будет рассматривать классы как одинаковые.

Я бы попробовал. Добавление пространства имен и восстановление ссылки.

0 голосов
/ 05 июня 2012

В запросе вы указываете, что тип содержимого запроса - "application / x-www-form-urlencoded".Но на самом деле это JSON (генерируется с использованием DataContractJsonSerializer).Попробуйте обновить тип контента до правильного («application / json»), и это поможет вам продвинуться дальше, где вам нужно.

0 голосов
/ 08 февраля 2011

Я считаю, что проблема заключается в том, что ваш тип отличается, вы используете прокси-класс и сериализуете его, а затем пытаетесь десериализовать его как другой тип, когда получаете его обратно на стороне сервера.

Вы должны иметь возможность добавить атрибут KnownType, я считаю, что это понадобится для автоматически сгенерированного прокси-класса.

...