当缺少所需字段时,我可以强制Azure API管理返回400而不是404吗?



我们有一个应用程序,它需要显示一些字段。如果这些字段不存在,我们将返回一个400响应,在正确的错误消息中解释丢失的内容。将APIM添加到组合中似乎会使其变得更加复杂。由于APIM知道该字段是必需的,所以它看起来会短路并返回404,并带有一条通用消息,而不是我们的自解释消息,说明什么是错误的。

这是一种将此功能转换为APIM的方法吗?

我遇到了同样的问题,我最终改变了我的方法。我所做的是在应用程序端配置它,并使用FluentValidation生成所需的查询字符串参数。所以,我的模型现在看起来像这样:

using FluentValidation;
public class UrlQueryParameters
{
public string PropertyA { get; set; }
public string PropertyB { get; set; }
}
public class UrlQueryParametersValidator : AbstractValidator<UrlQueryParameters>
{
public UrlQueryParametersValidator()
{
RuleFor(o => o.PropertyA)
.NotEmpty()
.WithMessage("The 'PropertyA' parameter was missing or a value was not provided.");
RuleFor(o => o.PropertyB)
.NotEmpty()
.WithMessage("The 'PropertyB' parameter was missing or a value was not provided.");
}
}

前面的代码为PropertyAPropertyB属性定义了一对带有自定义消息的验证规则。

现在,通过在Startup.cs文件的ConfigureServices方法中添加以下代码,启用FluentValidation作为我们应用程序的默认验证机制:

public void ConfigureServices(IServiceCollection services) {
// Rest of the code omitted for brevity

services
.AddControllers()
.AddFluentValidation(fv => 
{ 
fv.DisableDataAnnotationsValidation = true;

// The following line registers ALL public validators in the assembly containing UrlQueryParametersValidator
// There is no need to register additional validators from this assembly.
fv.RegisterValidatorsFromAssemblyContaining<UrlQueryParametersValidator>(lifetime: ServiceLifetime.Singleton);
});
}

此时,您的API端点应该验证请求所需的参数,并且当您试图访问/api/foo/{id}时,APIM不应该通过抛出404 Not Found来缩短请求。

这个工作的原因是因为Swashbuckle不会自动从FluentValidation导入验证规则。这意味着,当在Swagger UI中查看属性PropertyAPropertyB时,它们不会被标记为必需的。这是这种方法的缺点,因为Swagger UI中所需的查询字符串参数不会被标记为必需的,这可能会使消费者感到困惑。但对我来说,向消费者返回正确的StatusCode和有意义的消息更重要,这就是为什么我将暂时坚持这种解决方案。您可以尝试使用MicroElements.Swashbuckle.FluentValidation至少在Swagger UI模式中设置/标记所需的参数。但这就是它。

我在这里写了一篇博文:如何在Azure APIM中使用所需的QueryString参数

在API/Product/Global级策略添加on-error部分,使用choose policy检查是否发现操作:

<choose>
<when condition="@(context.LastError.Source == "configuration" && context.LastError.Reason == "OperationNotFound")">
<return-response>
<set-status code="400" reason="Bad Request" />
</return-response>
</when>
</choose>

最新更新