#c# #mongodb #json.net
#c# #mongodb #json.net
Вопрос:
может кто-нибудь помочь мне создать метод расширения для пользовательских атрибутов для newtonsoft.json и mongodb?
Допустим, у меня есть следующий класс:
public class Foo
{
[BsonElement("MyCustomDbName")]
[JsonProperty("MyCustomJsonName")]
public string Name { get; set; }
}
Как создать метод расширения, чтобы получить следующее:
var myFoo = new Foo(){Name=""};
var mongoDbElementName = myFoo.Name.GetMongoDbElementName(); // should return 'MyCustomDbName'
var jsonPropertyName = myFoo.Name.GetJsonPropertyName(); // should return 'MyCustomJsonName'
или непосредственно с самим классом:
var mongoDbElementName = Foo.Name.GetMongoDbElementName(); // should return 'MyCustomDbName'
var jsonPropertyName = Foo.Name.GetJsonPropertyName(); // should return 'MyCustomJsonName'
Я пробовал подобные вещи:
public static string GetMongoDbElementName(this Type modelType, PropertyInfo property)
{
return (modelType.GetProperty(nameof(property)) ?? throw new InvalidOperationException()).GetCustomAttribute<BsonElementAttribute>()?.ElementName;
}
Но есть ли способ сделать это без параметра?
Спасибо заранее
Ответ №1:
Вы не можете сделать это непосредственно в свойстве; вам нужно будет применить метод расширения к классу и использовать выражение для выбора свойства:
public static string GetMongoDbElementName<T>(
this T obj,
Expression<Func<T, object>> propertySelector)
{
var memberExpression = propertySelector.Body as MemberExpression;
var memberName = memberExpression?.Member.Name
?? throw new InvalidOperationException();
var bsonAttribute = obj
.GetType()
.GetProperty(memberName)
.GetCustomAttribute<BsonElementAttribute>();
return bsonAttribute?.ElementName;
}
Использование:
var mongoDbElementName = myFoo.GetMongoDbElementName(x => x.Name);
Вы также можете захотеть обновить код для защиты от выбора других элементов (например, метода), что можно сделать следующим образом:
var property = obj
.GetType()
.GetProperty(memberName)
?? throw new InvalidOperationException($"{memberName} is not a property");
var bsonAttribute = property
.GetCustomAttribute<BsonElementAttribute>();
Комментарии:
1. СПАСИБО, хорошее решение!!!
Ответ №2:
Вы можете получить атрибут и его значение, используя отражение:
public static string GetBsonElementName(this Foo foo)
{
var bsonElementAttribute =
typeof(Foo)
.GetProperty(nameof(Foo.Name))
.GetCustomAttribute<BsonElementAttribute>();
return bsonElementAttribute.ElementName;
}
public static string GetJsonPropertyName(this Foo foo)
{
var jsonPropertyAttribute =
typeof(Foo)
.GetProperty(nameof(Foo.Name))
.GetCustomAttribute<JsonPropertyAttribute>();
return jsonPropertyAttribute.PropertyName;
}
Вы используете его следующим образом:
var foo = new Foo();
var bsonElementName = foo.GetBsonElementName();
var jsonPropertyName = foo.GetJsonPropertyName();
Комментарии:
1. Это вряд ли будет полезно, учитывая, что оно жестко
Foo.Name
запрограммировано.2. Кроме того, что такое
BsonName
?