Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取linq表达式中的属性值_C#_Asp.net Mvc_Linq - Fatal编程技术网

C# 获取linq表达式中的属性值

C# 获取linq表达式中的属性值,c#,asp.net-mvc,linq,C#,Asp.net Mvc,Linq,我正在尝试使用linq表达式验证MVC代码中的电话号码。代码如下所示: class Person { public HomePhone { get; set; } } class Employee { public WorkPhone { get; set; } } class Office { Employee Boss { get; set; } } class PersonController : Controller { private static

我正在尝试使用linq表达式验证MVC代码中的电话号码。代码如下所示:

class Person
{
    public HomePhone { get; set; }
}

class Employee
{
    public WorkPhone { get; set; }
}

class Office
{
    Employee Boss { get; set; }
}

class PersonController : Controller
{
    private static ValidatePhoneNumber<M>(Exression<Func<M,string>> propExpr)
    {
        var member = prop.Body as MemberExpression;
        if (member == null)
        {
            throw new ArgumentException("expression must be a member expression, i.e., x => x.MyProperty");
        }

        var propInfo = member.Member as PropertyInfo;
        if (propInfo == null)
        {
            throw new ArgumentException("expression is not a property type.");
        }

        var getter = propExpr.Compile();
        string phoneStr = getter(); //this doesn't work

        if( !/* ... phoneStr is valid phone number */ )
        {
            var propName = propInfo.Name;
            ModelState[propName] = "invalid format for phone number";
        }
    }

    public ActionResult Create(Person p)
    {
        ValidatePhoneNumber( p => p.HomePhone );
                    if( ModelState.IsValid )
                    ....
    }

    public ActionResult CreatOffice(Office o)
    {
        ValidatePhoneNumber( o => o.Boss.WorkPhone );
                    if( ModelState.IsValid )
                    ....
    }
}
班级人员
{
公用家庭电话{get;set;}
}
班级员工
{
公用工作电话{get;set;}
}
班级办公室
{
员工上司{get;set;}
}
类PersonController:Controller
{
私有静态ValidatePhoneNumber(Expression PropertExpr)
{
var member=prop.Body作为MemberExpression;
if(成员==null)
{
抛出新ArgumentException(“表达式必须是成员表达式,即x=>x.MyProperty”);
}
var propInfo=member.member作为PropertyInfo;
if(propInfo==null)
{
抛出新ArgumentException(“表达式不是属性类型”);
}
var getter=propExpr.Compile();
字符串phoneStr=getter();//这不起作用
如果(!/*…phoneStr是有效的电话号码*/)
{
var propName=propInfo.Name;
ModelState[propName]=“电话号码格式无效”;
}
}
公共行动结果创建(人员p)
{
验证电话号码(p=>p.HomePhone);
if(ModelState.IsValid)
....
}
公共行动办公室(o办公室)
{
ValidatePhoneNumber(o=>o.Boss.WorkPhone);
if(ModelState.IsValid)
....
}
}

我不能完全理解这里需要的语法。我需要做什么才能拥有一个函数,在这个函数中我传入一个成员属性表达式,并可以访问该属性的名称及其值。

仅凭反射就可以得到您想要的结果

namespace Forums.LinqToValidatePhoneNumberProperty
{
    using System;
    using System.Linq;
    using System.Reflection;
    using System.Text.RegularExpressions;

    public class PhoneNumberRule
    {
        #region Fields

        static string _usPhonePattern = @"1?\W*([2-9][0-8][0-9])" +
                                        @"\W*([2-9][0-9]{2})\W*" +
                                        @"([0-9]{4})(\se?x?t?(\d*))?";
        static Regex _usPhoneRegex = new Regex( _usPhonePattern );

        #endregion Fields

        #region Methods

        public static void Validate( object target, string propertyName )
        {
            Type targetType = target.GetType();
            PropertyInfo targetProperty = 
                ( from propertyInfo in targetType.GetProperties()
                where ( propertyInfo.Name == propertyName
                && propertyInfo.PropertyType.IsAssignableFrom(  
                    typeof (string ) ) )
                select propertyInfo ).First();

            if ( targetProperty == null )
            {
                throw new InvalidOperationException( "No appropriate property " +
                                                     "could be found on the " + 
                                                     "target object." );
            }

            string testValue = targetProperty.GetValue( target, null ) as string;

            if ( testValue != null && _usPhoneRegex.IsMatch( testValue ) )
            {
                return;
            }
            else
            {
                ModelState[propertyName] = "Not a valid phone number format";
            }
        }

        #endregion Methods
    }
}
更可靠的解决方案可能是使用反射和自定义属性的组合

    public class PhoneNumberRule
    {
        #region Fields

        static string _usPhonePattern = @"1?\W*([2-9][0-8][0-9])" +
                                        @"\W*([2-9][0-9]{2})\W*" +
                                        @"([0-9]{4})(\se?x?t?(\d*))?";
        static Regex _usPhoneRegex = new Regex( _usPhonePattern );

        #endregion Fields

        #region Methods

        public static void ValidateProperties( object target )
        {
            Type targetType = target.GetType( );
            var phoneNumberProperties =
                from propertyInfo in targetType.GetProperties( )
                where propertyInfo.GetCustomAttributes(
                    typeof( PhoneNumberAttribute ), true ).Length > 0
                select propertyInfo;
            foreach ( PropertyInfo targetProperty in phoneNumberProperties )
            {
                string value = targetProperty.GetValue( target, null) as string;
                if ( value == null || !_usPhoneRegex.IsMatch( value ) )
                {
                    ModelState[ targetProperty.Name ] = "Not a valid phone number format";
                }
            }
        }

    }

    [AttributeUsage(AttributeTargets.Property)]
    public class PhoneNumberAttribute : Attribute
    {
    }

    public class Person
    {
        [PhoneNumber( )]
        public string HomePhone { get; set; }
    }

在Create和createOffice方法中声明的p和o与在lambda表达式中声明的p和o不同。事实上,您应该得到一个错误,因为标识符已经存在于当前范围中

我会将您的方法修改为扩展方法。(需要在静态类中定义)

您的用法将被修改为

public ActionResult Create(Person p)
{
    p.ValidatePhoneNumber( person => person.HomePhone );
                if( ModelState.IsValid )
                ....
}

我不认为您提供的代码可以编译(不,我不是说
)。这是您试图解决问题的实际代码吗?当有这么多方法验证属性时,您为什么要重新发明轮子?
propertyInfo.GetValue(obj, null);
public ActionResult Create(Person p)
{
    p.ValidatePhoneNumber( person => person.HomePhone );
                if( ModelState.IsValid )
                ....
}