Может ли объект, возвращенный из другого домена приложения, быть сериализован в вызывающем домене?
В следующем коде, когдаSerializeToJson()
метод вызван, я получаю следующее исключение на WriteObject()
:
Remoting не может найти поле "__identity" по типу "System.MarshalByRefObject"
Что я пытаюсь сделать возможным? Я немного незнаком с доменами приложений и связанными с ними вещами (прозрачный прокси и т. Д.). Я могу сериализовать свой TestClass в текущем домене приложения, но не понимаю, почему он здесь не работает. Спасибо за поиск.
using System;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
namespace ConsoleApplication6
{
public class BaseClass : MarshalByRefObject { }
public class RemoteClass : BaseClass
{
public TestClass DoIt()
{
return new TestClass { Prop1 = DateTime.Now, Prop2 = 1234 };
}
}
[DataContract]
public class TestClass : MarshalByRefObject
{
public TestClass() { }
public TestClass(TestClass tc)
{
Prop1 = tc.Prop1;
Prop2 = tc.Prop2;
}
[DataMember]
public DateTime Prop1 { get; set; }
[DataMember]
public int Prop2 { get; set; }
}
class Program
{
static void Main(string[] args)
{
var appDomain = AppDomain.CreateDomain("myappdomain");
var remoteClass = (RemoteClass)appDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(RemoteClass).FullName);
var returnedTestClass = remoteClass.DoIt();
Console.WriteLine(SerializeToJson(returnedTestClass));
}
private static string SerializeToJson(object obj)
{
try
{
using (var stream = new MemoryStream())
{
var serializer = new DataContractJsonSerializer(obj.GetType());
serializer.WriteObject(stream, obj);
stream.Position = 0;
using (var streamReader = new StreamReader(stream))
{
return streamReader.ReadToEnd();
}
}
}
catch (Exception e)
{
// Error: Remoting cannot find field '__identity' on type 'System.MarshalByRefObject'.
Console.WriteLine(e.Message);
return string.Empty;
}
}
}
}
2 ответа
Не надо смешивать [DataContract]
с MarshalByRefObject
для.NET Remoting. Просто используйте MarshalByRefObject
как ты сделал с RemoteClass
Это может быть возможно с Protobuf:
https://github.com/mgravell/protobuf-net
Тем не менее, я хотел бы предупредить, что, основываясь на использовании [DataContract], он пахнет как WCF, который обычно является дорогой с односторонним движением. WCF печально известен тем, что диктует вам, как вы должны написать свое приложение - и это включает в себя сериализацию.
При этом у меня никогда не было проблем с JSON.Net для сериализации классов, помеченных [DataContract]. JsonConvert.Serialize() работает против System.Object.