已验证 TryParse 和 BindAsync 方法

ASP.NET Core 现在会验证 Map* 方法的参数类型上的 TryParseBindAsync 方法。 如果找不到有效方法,ASP.NET Core 会查找无效方法,如果找到,则会在启动时引发异常。 该异常会提醒你方法签名可能不正确,因而有助于避免出现意外的行为。

引入的版本

ASP.NET Core 6.0 RC 2

旧行为

在以前的 ASP.NET Core 6 版本中,如果 TryParseBindAsync 方法的签名无效,则不会引发异常,并且框架会尝试从主体绑定 JSON。

// Todo.TryParse is not in a valid format.
// Will try to bind from body as JSON instead.
app.MapPost("/endpoint", (Todo todo) => todo.Item);

public class Todo
{
    public string Item { get; set; }
    public static bool TryParse(string value) => true;
}

新行为

如果 ASP.NET Core 找到与预期语法不匹配的公共 TryParseBindAsync 方法,则会在启动时引发异常。 上面的示例生成如下所示的错误:

TryParse method found on Todo with incorrect format. Must be a static method with format
bool TryParse(string, IFormatProvider, out Todo)
bool TryParse(string, out Todo)
but found
Boolean TryParse(System.String)

中断性变更的类型

此项更改可能会影响二进制兼容性源兼容性

更改原因

做出此项更改的原因是使开发人员意识到 BindAsyncTryParse 方法采用了无效的格式。 以前,框架会回退为假设参数是来自主体的 JSON。 这种假设可能会导致意外行为。

如果类型的 BindAsyncTryParse 方法出于某种原因(与参数绑定相关的原因除外)而使用不同的语法,那么现在你在启动时会遇到异常。 为了避免此行为,可以使用多种策略:

  • BindAsyncTryParse 方法更改为 internalprivate
  • 添加一个新的使用框架所查找的语法的 BindAsyncTryParse 方法,如果找到有效的方法,则会忽略无效的方法。
  • 将参数标记为 [FromBody]

受影响的 API

  • RequestDelegateFactory.Create()
  • 所有 IEndpointRouteBuilder.Map*() 方法,例如 app.MapGet()app.MapPost()