gpt4 book ai didi

c# - 自定义类包含另一个自定义类时的 DataContractResolver/KnownType 问题

转载 作者:太空狗 更新时间:2023-10-29 23:10:28 27 4
gpt4 key购买 nike

我正在尝试使用 DataContractJsonSerializer 类将对象列表输出为 json 格式,但是我一直遇到以下错误。

Type 'Castle.Proxies.JokeCategoryProxy' with data contract name 
'JokeCategoryProxy:http://schemas.datacontract.org/2004/07/Castle.Proxies'
is not expected. Consider using a DataContractResolver or 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.

我知道之前已经回答过这个问题,但它似乎只有在我的对象中有一个属性是另一个自定义对象时才会发生。

[DataContract]
[KnownType(typeof(ModelBase<int>))]
public class Joke : ModelBase<int>
{
[DataMember]
public virtual string JokeText { get; set; }

[DataMember]
public virtual JokeCategory JokeCategory { get; set; }
}

[DataContract]
[KnownType(typeof(ModelBase<int>))]
public class JokeCategory : ModelBase<int>
{
[DataMember]
public virtual string Name { get; set; }
}

如您所见,笑话模型包含一个笑话类别对象,如果我删除笑话类别并只使用一个 int (JokeCategoryId),错误就会消失,尽管这是一个解决方案,但不是理想的解决方案,因为我希望拥有类别无需再次查询即可获得。

下面是我用来生成json的代码

    public static ContentResult JsonResponse<TReturnType>(this Controller controller, TReturnType data)
{
using (var oStream = new System.IO.MemoryStream())
{
new DataContractJsonSerializer(typeof(TReturnType)).WriteObject(oStream, data);

return new ContentResult
{
ContentType = "application/json",
Content = Encoding.UTF8.GetString(oStream.ToArray()),
ContentEncoding = Encoding.UTF8
};
}
}

最让我困惑的是错误引用了 CaSTLe.Proxies.JokeCategoryProxy(这是从哪里来的?!)

有什么建议吗?

最佳答案

nHibernate 假定您的所有属性,除非另有说明,都是延迟加载的。
这意味着,在您的情况下,无论何时拉取 Joke 对象,都不会从数据库中拉取 JokeCategory;相反,“代理”是动态生成的。
第一次访问该属性时,nHibernate 知道从数据库中提取它。 (这就是 nHib 的延迟加载的工作原理)

所以基本上这里发生的事情是您希望您的 JokeCategoryJokeCategory 类型,但由于它没有真正初始化 - 它是 类型代理...

(这只是一个简短的解释;在 google 上搜索更多关于 nHib 及其工作原理的信息。您还可以查看 summer of nhibernate 以了解有关此 ORM 的精彩介绍)

而且,对于你的问题:你在这里有几个选择:

  1. 将您的 Category 属性配置为非惰性,这将强制 nHibernate 使用正确的对象类型对其进行初始化

  2. (在我看来更可取)不要序列化您的模型实体;相反 - 构建某种 DTO 来保存您的表示层需要的任何信息。
    这样,您的演示文稿就不会受到域模型更改的影响,反之亦然。
    此外,您可以在 DTO 中保存所有必要的信息,即使它与多个模型实体相关。

例如:

  public class JokeDTO
{
public int JokeId;
/*more Joke properties*/
public int JokeCategoryId;
public string JokeCategoryName;
/*etc, etc..*/
}

关于c# - 自定义类包含另一个自定义类时的 DataContractResolver/KnownType 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6622806/

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