Я ищу способ получить имя и ценность протеи в объекте POCO. Я пробовал много решений, но не могу заставить их работать. Мне очень понравилось this старое решение, но оно вызывает ошибку null ref.Получить имя и значение свойства объекта POCO с помощью выражения
Вот вроде того, что я пытаюсь сделать:
public class POCO
{
public int ID { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Description { get; set; }
}
public class POCOValidationResult
{
public bool IsValid { get; set; }
public string Error { get; set; }
}
public abstract class Validator<T> where T : class
{
public T Entity { get; set; }
public abstract POCOValidationResult Validate();
protected POCOValidationResult ValidateStringPropertyToLengthOf(Expression<Func<T, object>> expression, int maxLength)
{
var propertyName = getPropertyName(expression);
var propertyValue = getPropertyValue(expression);
if (propertyValue.Length > maxLength)
{
return new POCOValidationResult()
{
Error = string.Format("{0} value is too long. Must be less or equal to {1}", propertyName, maxLength.ToString())
};
}
return new POCOValidationResult() { IsValid = true };
}
internal string getPropertyName(Expression<Func<T, object>> expression)
{
var memberExpersion = (MemberExpression)expression.Body;
return memberExpersion.Member.Name;
}
internal string getPropertyValue<R>(Expression<Func<T, R>> expression)
{
//struggling to get this to work
var me = (MemberExpression)expression.Body; // (MemberExpression)((MemberExpression)expression.Body).Expression;
var ce = (ConstantExpression)me.Expression; // Error here!
var fieldInfo = ce.Value.GetType().GetField(me.Member.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
var value = fieldInfo.GetValue(ce.Value);
}
}
public class POCOValidator : Validator<POCO>
{
public override POCOValidationResult Validate()
{
var surnameValidationResult = ValidateStringPropertyToLengthOf(p => p.Surname, 10);
if (!surnameValidationResult.IsValid)
return surnameValidationResult;
//var descriptionValidationResult = ValidateStringPropertyToLengthOf(p => p.Description, 100);
//if (!descriptionValidationResult.IsValid)
// return descriptionValidationResult;
//var nameValidationResult = ValidateStringPropertyToLengthOf(p => p.Name, 15);
//if (!nameValidationResult.IsValid)
// return nameValidationResult;
return new POCOValidationResult() { IsValid = true };
}
}
public class WorkerBee
{
public void ImDoingWorkReally()
{
var pocoVallidation = new POCOValidator()
{
Entity = new POCO()
{
ID = 1,
Name = "James",
Surname = "Dean",
Description = "I'm not 007!"
}
};
var vallidationResult = pocoVallidation.Validate();
if (!vallidationResult.IsValid)
{
return;
}
//continue to do work...
}
}
class Program
{
static void Main(string[] args)
{
var workerBee = new WorkerBee();
workerBee.ImDoingWorkReally();
}
}
Так как вы можете видеть, я пытаюсь получить имя и значение свойства [с помощью Expression (p => p.Surname)
в качестве параметра в способ ValidateStringPropertyToLengthOf(...)
]. Проблема в том, что я получаю ошибку null ref в getPropertyValue(Expression<Func<T, object>> expression)
, когда он вызывает var ce = (ConstantExpression)me.Expression;
У кого-нибудь есть идеи о том, как заставить это работать?
Спасибо, что нашли время, чтобы изучить это. Я очень ценю это и надеюсь, что мой вопрос также будет полезен для других, поскольку я думаю, что это может быть весьма полезно, если я смогу заставить это работать.
EDIT: Я сделал изменения, как указано ниже в комментариях и по-прежнему получаю сообщение об ошибке «Не удается привести объект типа„System.Linq.Expressions.TypedParameterExpression“к типу«System.Linq.Expressions. ConstantExpression ", когда я запускаю свой модульный тест.
Я уверен, что это будет объяснить проблему http://stackoverflow.com/questions/3567857/why-are- some-object-properties-unaryexpression-and-others-memberexpression/3573250 # 3573250 Пожалуйста, удалите свой вопрос, если это так. – leppie
Это похоже на дубликат для меня. По совету leppie вы должны изменить объявление метода на 'string getPropertyValue (выражение > выражение)', чтобы был передан правильный тип выражения (т. Е. Один с телом). Я потратил 5 минут, чтобы проверить его сам, но вы не потрудились включить [минимальный, полный пример кода] (http://stackoverflow.com/help/mcve). –
Я ценю помощь, но изменение объявления не помогло, так как я все еще получаю ту же ошибку: «Невозможно передать объект типа« System.Linq.Expressions.TypedParameterExpression »для ввода« System.Linq.Expressions.ConstantExpression ». " – MaudDib