gpt4 book ai didi

c# - JSON 反序列化中的类型提示

转载 作者:太空宇宙 更新时间:2023-11-03 13:16:17 25 4
gpt4 key购买 nike

我一直在使用 ASP.NET (asmx) WebService 通过 AJAX 与服务器通信。我现在正在我的 WebMethods 中使用复杂类型。我的问题是我的一个类有一个类型为接口(interface)的属性。

当序列化时,一切都很好,因为实例类型是已知的。反序列化 JSON 转换器不知道要转换成的类型,因为它无法创建我的接口(interface)的实例。所以我看了一下Type Hinting特别是多态部分,我一直在努力让它工作,但没有成功。

这是我的代码示例:

[WebService(Namespace = "http://tempuri.org/")] 
[ScriptService]
public class MyService : System.Web.Services.WebService {

public MyService () { }

[WebMethod(EnableSession = true)]
[ScriptMethod]
public void SaveThing(Thing myThing)
{
//Do stuff
}
}

public interface IItem : ISerializable
{
int Id { get; }
string Options { get; }
}

[DataContract(Namespace="MyNamespace", Name="Item")]
public class Item : IItem
{
[DataMember]
public string Url
{
get { return m_url; }
}
}

[Serializable]
public class Thing
{
public int Id { get; set; }
public IItem MyItem { get; set; }
}

我在序列化时获得了 myThing (Thing)__type 属性,但属性 MyItem (Item) 没有。我尝试通过操纵 JSON 并将其发回来强制执行它,但我只是得到 InvalidServiceOperation。我是否在尝试不允许的事情? MSDN 文档似乎没有提到我不能使用实例化类型提示反序列化到接口(interface),但它的示例确实暗示了类和派生类。

如果可能的话,我想继续使用属性进行序列化而不是自定义代码,只是因为我认为它更整洁。尽管如此,仍然对编码解决方案持开放态度。

最佳答案

是的,经过更多的搜索和研究,我想出了一个解决方案,它不像我想要的那样整洁和漂亮,但它有效。

首先是什么不起作用。所以我尝试使用 ISerializable,使用 GetObjectData() 和反序列化构造函数实现了我的类:

[Serializable]
public class Thing : ISerializable
{
public int Id { get; set; }
public IItem MyItem { get; set; }

public Thing(SerializationInfo info, StreamingContext context){
{
//Do deserialization and handle IItem object
}

public void GetObjectData(SerializationInfo info, StreamingContext context)
{
//Do serialization
}
}

现在我认为这不起作用,因为在调用此构造函数之前,Thing 的所有属性都被反序列化,导致 native 序列化程序尝试反序列化我的接口(interface)。

关于什么起作用了。自定义 JavascriptConverter 来拯救。所以我更改了我的 web 服务以将字符串作为参数而不是复杂的对象(我不太喜欢这一点),然后实现了一个 JavascriptConverter 具有已知类型的 IItem 将反序列化处理为具体类。

public class ItemConverter : JavaScriptConverter
{
public override IEnumerable<Type> SupportedTypes
{
get { return new List<Type>() { typeof(IItem) }; }
}

public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
throw new NotImplementedException();
}

public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
//If we are of type IItem
if (dictionary.ContainsKey("Type")) //My check to make sure we are of type IItem
{
var factory = new ItemFactory();
return factory.CreateItem((int)dictionary["Id"], (string)dictionary["Options"], (ItemTypes)dictionary["Type"]);
}
else
{
return null;
}
}
}

[WebService(Namespace = "http://tempuri.org/")]
[ScriptService]
public class MyService : System.Web.Services.WebService {

public MyService () { }

[WebMethod(EnableSession = true)]
[ScriptMethod]
public void SaveThing(string myThing)
{
//Get our custom converter
var itemConverter = new ItemConverter();
var serialiser = new JavaScriptSerializer();
//Register it
serialiser.RegisterConverters(new List<JavaScriptConverter>() { itemConverter });
//Deserialise the dashboard
var theThing = serialiser.Deserialize<Thing>(myThing);

//Save
theThing.Save();
}
}

我希望这对某些人有所帮助,如果有人有任何更优雅的解决方案,我很乐意看到它们。另外在旁注中,在整个过程中,我不想对第三方库有任何依赖性,例如 Json.NETNewtonSoft JSON 等。

关于c# - JSON 反序列化中的类型提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25992192/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com