You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从SSv6.x迁移至SS8.x后ServiceStack ValidationRules不生效问题

问题描述

我们有一个基于.NET 6、ServiceStack 6.x的项目,使用AutoQuery生成DTO并通过运行x csharp命令保存到项目中,示例DTO如下:

[Route("/vehicles", "GET")]
[Route("/vehicles/{Id}", "GET")]
[DataContract]
public class QueryVehicles
    : QueryDb<Vehicle>, IReturn<QueryResponse<Vehicle>>, IGet
{
    [DataMember(Order = 1)]
    public long? Id { get; set; }
}

[Route("/vehicletypes", "GET")]
[Route("/vehicletypes/{Id}", "GET")]
[DataContract]
public class QueryVehicleTypes
    : QueryDb<VehicleType>, IReturn<QueryResponse<VehicleType>>, IGet
{
    [DataMember(Order = 1)]
    public long? Id { get; set; }
}

我们通过ValidationRule表配置动态验证规则,上述两个DTO需应用IsAuthenticated规则。
该配置在.NET6/SS6.x中运行正常,但迁移至.NET8/SS8.2.2后,IsAuthenticated验证规则不再生效,未登录即可查询这些端点。
有趣的是,我们重写了部分AutoQuery服务(如下示例),这类端点的IsAuthenticated ValidationRule是生效的:

public class CompaniesService : Service
{
    public IAutoQueryDb AutoQuery { get; set; }
    public IDbConnectionFactory ConnectionFactory { get; set; }

    public CompaniesService(IDbConnectionFactory dbConnectionFactory)
    {
        ConnectionFactory = dbConnectionFactory;
    }
    public async Task<object> Any(QueryCompanies query)
    {
        using var db = AutoQuery.GetDb(query, base.Request);
        var q = AutoQuery.CreateQuery(query, base.Request, db);
        if (query.CompanyTypeId.HasValue)
        {
            var session = await SessionAsAsync<SeritiUserSession>();
            q = q
                .Join<CompanyCompanyTypeMapping>()
                .Where<CompanyCompanyTypeMapping>(x => x.CompanyTypeId == query.CompanyTypeId)
                .Where<Company>(x => x.CountryId == session.CountryId);
            var implicitJoin = db.Select(q);
            return await AutoQuery.ExecuteAsync(query, q, base.Request, db);
        }
        else
        {
            return await AutoQuery.ExecuteAsync(query, q, base.Request, db);
        }

    }
}

请问这是什么原因导致的?

原因分析

这是ServiceStack 8.x对AutoQuery内置服务的验证规则应用逻辑做了调整导致的:

  • 在ServiceStack 6.x中,通过ValidationRule表配置的动态验证规则会自动应用到所有匹配的请求DTO,包括AutoQuery生成的QueryDb类对应的内置AutoQuery服务。
  • 而ServiceStack 8.x中,为了优化AutoQuery的默认性能,内置AutoQuery服务默认不再自动应用全局/动态配置的ValidationRule,仅当请求DTO对应自定义服务(即你重写的CompaniesService这类手动实现的服务)时,才会触发动态验证规则的校验。

简单来说,直接继承QueryDb但未手动实现服务类的AutoQuery内置通用服务,在SS8中默认跳过了动态ValidationRule的校验;而手动实现的服务类因为走标准Service请求处理流程,所以依然会正常应用验证规则。

解决办法

要让AutoQuery内置服务也应用动态ValidationRule,可选择以下方式处理:

  1. 全局启用AutoQuery验证:在AppHost配置AutoQueryFeature时开启ValidateAutoQueryRequests选项:
Plugins.Add(new AutoQueryFeature {
    ValidateAutoQueryRequests = true
});

该配置会让AutoQuery内置服务重新启用对全局/动态ValidationRule的校验。

  1. 给DTO添加强制验证特性:直接在AutoQuery生成的DTO类上添加[Validate]特性,强制触发验证规则:
[Route("/vehicles", "GET")]
[Route("/vehicles/{Id}", "GET")]
[DataContract]
[Validate] // 添加此特性
public class QueryVehicles
    : QueryDb<Vehicle>, IReturn<QueryResponse<Vehicle>>, IGet
{
    [DataMember(Order = 1)]
    public long? Id { get; set; }
}
  1. 手动实现AutoQuery服务:类似CompaniesService,为每个AutoQuery DTO创建对应的服务类,自动走标准服务验证流程,动态规则会正常生效。

内容的提问来源于stack exchange,提问作者Shawn de Wet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 20:23:14