我尝试使用NEST 2.X和Elastic Search来持久存储用户。每个用户都包含一个角色列表,用于在我们的平台内定义其权限。
有几种不同类型的角色,每种角色都来自IMediaDetectionRole界面:
public class MediaDetectionUser
{
public string Username { get; set; }
public ICollection<IMediaDetectionRole> Roles { get; set; }
public MediaDetectionUser()
{
Roles = new List<IMediaDetectionRole>();
}
}
public interface IMediaDetectionRole
{
string Name { get; }
string GetDescription();
string GetRoleType {get;}
}
[ElasticsearchType(Name="MediaDetectionAdminRole")]
public class MediaDetectionAdminRole : IMediaDetectionRole
{
public string Name { get { return "Admin"; } }
public string GetDescription() { return "Admin users can create other users within the account"; }
public string GetRoleType { get { return this.GetType().Name; } }
}
[ElasticsearchType(Name = "MediaDetectionManagerRole")]
public class MediaDetectionManagerRole : IMediaDetectionRole
{
public string Name { get { return "Manager"; } }
public string GetDescription() { return "Managers can modify account-level properties"; }
public string GetRoleType { get { return this.GetType().Name; } }
}
[ElasticsearchType(Name = "MediaDetectionCreatorRole")]
public class MediaDetectionCreatorRole : IMediaDetectionRole
{
public string Name { get { return "Creator"; } }
public string GetDescription() { return "Creators can create new Media Detection Profiles"; }
public string GetRoleType { get { return this.GetType().Name; } }
}
我没有在ElasticSearch中存储数据时遇到任何问题,但是当我去查询数据时,数据NEST无法确定这些角色的类型。我明白了:
Could not create an instance of type IMediaDetectionRole.
Type is an interface or abstract class and cannot be instantiated.
Path 'hits.hits[0]._source.roles[0].name', line 1, position 343.
将嵌套对象数据映射回正确的类类型的正确方法是什么?
非常感谢!
-Z
答案 0 :(得分:1)
好吧,所以我想这不是一个NEST / ES问题,更多的是JSON.NET问题。显然,这个问题的解决方案是告诉JSON.NET为列表的每个成员提供类型提示。
Per @ MartijnLaarman的建议我在Roles属性中添加了[JsonProperty]属性。见下文:
public class MediaDetectionUser
{
public string Username { get; set; }
//This JsonProperty helps reference the types during deserialization
[JsonProperty("Roles", ItemTypeNameHandling = TypeNameHandling.All)]
public ICollection<IMediaDetectionRole> Roles { get; set; }
public MediaDetectionUser()
{
Roles = new List<IMediaDetectionRole>();
}
}
这是一个JSON的例子,因为它出现在ElasticSearch里面的_source中:
Roles: [
{
$type: "MediaDetectionFrontend.ServiceModel.Types.MediaDetectionAdminRole, MediaDetectionFrontend.ServiceModel",
name: "Admin",
getRoleType: "MediaDetectionAdminRole"
},
{
$type: "MediaDetectionFrontend.ServiceModel.Types.MediaDetectionCreatorRole, MediaDetectionFrontend.ServiceModel",
name: "Creator",
getRoleType: "MediaDetectionCreatorRole"
},
{
$type: "MediaDetectionFrontend.ServiceModel.Types.MediaDetectionEditorRole, MediaDetectionFrontend.ServiceModel",
name: "Editor",
getRoleType: "MediaDetectionEditorRole"
}
]
您可以看到$ type属性现在提供List中每个元素的完整类型描述符。
非常感谢@MartijnLaarman帮我解决了这个问题,尽管它与ElasticSearch和NEST毫无关系。