当我使用 class 类型作为参数时,为什么我的 razor 页面中的模型状态无效?

Why is the modelstate invalid in my razor page when I use a class type as a parameter?

这是我第一次尝试在 ASP.Net Core 2.2 中使用 Razor Pages,我正在使用页面过滤器检查 ModelState.IsValid,它在 GET 请求时返回 false我在导致页面失败的 OnGet() 方法参数中使用了一个类型。如果我更改方法的签名以使用原始类型,则模型状态有效。

举例如下:

对于下面的代码,

ModelState.IsValidfalse,它在 ASP.Net Core 2.2 MVC 中的控制器操作中运行良好:

public class IndexModel : PageModel
{
    public string IsValid { get; set; }

    public void OnGet(Query query)
    {
        // FALSE
        IsValid = ModelState.IsValid.ToString();
    }

    public class Query
    {
        public int? Page { get; set; }
    }
}

但对于以下情况正确

public class IndexModel : PageModel
{
    public string IsValid { get; set; }

    public void OnGet(int? query)
    {
        // TRUE
        IsValid = ModelState.IsValid.ToString();
    }
}

为什么会这样?

Razor Pages, by default, bind properties only with non-GET verbs.

引用Introduction to Razor Pages in ASP.NET Core

因为默认情况下,GET 无法绑定到复杂对象。需要应用模型绑定属性。

你必须明确地告诉它你想从哪里绑定。

例如

public void OnGet([FromQuery]Query query) {
   IsValid = ModelState.IsValid.ToString();
}

您可以将 Query 类型作为参数应用到 OnGet 方法,而不是将其添加为 PageModel 属性,并用 BindProperty 属性装饰:

public class IndexModel : PageModel
{
    public string IsValid { get; set; }

    [BindProperty(SupportsGet=true)]
    public Query query { get; set; }

    public void OnGet()
    {

    }

    public class Query
    {
        public int? Page { get; set; }
    }
} 

当使用 BindProperty 属性时,您必须选择在 GET 请求中进行绑定(因此 SupportsGet=true),但是当您使用 PageModel 属性时,您不需要告诉模型绑定从哪里获取值。它会自动搜索查询字符串、请求正文、路由数据等

更多信息:https://www.learnrazorpages.com/razor-pages/model-binding#binding-data-from-get-requests