C# 如何在OnActionExecuting中从模型中获取属性值

C# 如何在OnActionExecuting中从模型中获取属性值,c#,asp.net-core,.net-5,asp.net-core-5.0,C#,Asp.net Core,.net 5,Asp.net Core 5.0,我正在做一个Asp.Net core 5项目,目标是.Net 5 在许多情况下,在我使用的视图中,select列表和从列表中选择的值将受model属性之一的影响 我熟悉操作过滤器,但在我的级别上是初学者,所以我尝试创建一个自定义过滤器,它将检查模型中的属性值是否等于默认值我将添加一个错误模型状态,所有这些代码都应该在操作执行方法中发生 我的尝试: public class CheckDefaultOptionFromSelect : ActionFilterAttribute {

我正在做一个
Asp.Net core 5
项目,目标是
.Net 5

在许多情况下,在我使用的视图中,
select
列表和从列表中选择的值将受
model
属性之一的影响

我熟悉
操作过滤器
,但在我的级别上是初学者,所以我尝试创建一个自定义过滤器,它将检查
模型
中的
属性
值是否等于
默认值
我将添加一个错误
模型状态
,所有这些代码都应该在
操作执行
方法中发生

我的尝试:

public class CheckDefaultOptionFromSelect : ActionFilterAttribute
    {

        /// <inheritdoc />
        public override void OnActionExecuting( ActionExecutingContext context )
        {
            var model = ( (Controller) context.Controller ).ViewData.Model;

            if ( model is not null )
            {
                foreach ( var property in model.GetType().GetProperties() )
                {

                        if ( (string) model.GetType().GetProperty( property.Name ).GetValue( model ).ToString() == "default_option" )
                        {
                            context.ModelState.AddModelError( "" , "Please select an option" );

                            base.OnActionExecuting( context );
                            break;
                        }
                }
            }
        }

    }
公共类CheckDefaultOptionFromSelect:actionfilteratAttribute
{
/// 
公共重写无效OnActionExecuting(ActionExecutingContext上下文)
{
var模型=((Controller)context.Controller).ViewData.model;
if(模型不为空)
{
foreach(model.GetType().GetProperties()中的var属性)
{
if((字符串)model.GetType().GetProperty(property.Name).GetValue(model.ToString()==“默认选项”)
{
context.ModelState.AddModelError(“,”请选择一个选项”);
base.OnActionExecuting(上下文);
打破
}
}
}
}
}
在这些操作中,视图将包含以下内容:

public class CheckDefaultOptionFromSelect : ActionFilterAttribute
    {

        /// <inheritdoc />
        public override void OnActionExecuting( ActionExecutingContext context )
        {
            var model = ( (Controller) context.Controller ).ViewData.Model;

            if ( model is not null )
            {
                foreach ( var property in model.GetType().GetProperties() )
                {

                        if ( (string) model.GetType().GetProperty( property.Name ).GetValue( model ).ToString() == "default_option" )
                        {
                            context.ModelState.AddModelError( "" , "Please select an option" );

                            base.OnActionExecuting( context );
                            break;
                        }
                }
            }
        }

    }

默认选项

您需要获得如下所示的模型数据:

public class CheckDefaultOptionFromSelect : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        context.ActionArguments.TryGetValue("model", out object model);

        if (model is not null)
        {
            foreach (var property in model.GetType().GetProperties())
            {
                if ((string)model.GetType().GetProperty(property.Name).GetValue(model).ToString() == "default_option")
                {
                    context.ModelState.AddModelError("", "Please select an option");
                    base.OnActionExecuting(context);
                    break;
                }
            }
        }
    }
}
整个测试代码:

型号:

public class Test2
{
    public int Id { get; set; }
    public string Title { get; set; }
}
public class TestViewModel
{
    public string PropertyName { get; set; }
}
视图:

注意:由于添加了带有空键的modelstate,因此
asp validation for=“PropertyName”
不会显示错误。确保添加
以显示所有模型错误

@model TestViewModel 
@{ 
    var myCollection = new List<Test2>()
    {
        new Test2(){ Id=1,Title="aaa"},
        new Test2(){Id=2,Title="bbb"},
        new Test2(){Id=3,Title="ccc"}
    };
}
<form method="post" asp-action="Index">
    <div class="col-lg-4 col-sm-6">
        <div class="form-group"> 

            <div asp-validation-summary="ModelOnly" class="text-danger"></div> 

            <div class="form-control-wrap">
                <select asp-for="PropertyName" asp-items="@(new SelectList(myCollection,"Id","Title") )" class="form-select form-control form-control-lg form-control-outlined" data-ui="lg" data-search="on">
                    <option value="default_option">Default Option</option>
                </select>
                <label asp-for="PropertyName" class="form-label-outlined"></label>
                <span asp-validation-for="PropertyName" class="text-danger"></span>
            </div>
        </div>
    </div>
    <input value="Create" type="submit" />
</form>
在Startup.cs中注册
ActionFilterAttribute

services.AddScoped<CheckDefaultOptionFromSelect>();
services.addScope();

我相信模型是通过参数绑定的,并且至少在执行操作之前的阶段不会与
ViewData.model进行同步。因为它绑定到所有操作的参数,所以需要更具体地说明过滤器应用的操作(或者至少显示所应用操作的所需签名)。您将从
上下文中获得参数。ActionArguments
)。哦,我真的很感谢您,这是非常有用的。谢谢,上帝保佑您