运行 通过网关时,AutoQuery 未获取名称数据库连接

AutoQuery is not getting the name db connection when run through gateway

我有一个实现,我通过服务网关调用自动查询操作。服务网关将成功调用内部和外部操作。但是,任何自动查询操作都会失败,因为它没有设置连接字符串。这些相同的自动查询操作在直接调用而不是通过网关调用时工作得很好。

这是堆栈跟踪。

at ServiceStack.OrmLite.OrmLiteConnectionFactory.CreateDbConnection() in C:\BuildAgent\work\27e4cc16641be8c0\src\ServiceStack.OrmLite\OrmLiteConnectionFactory.cs:line 70\r\n   at ServiceStack.OrmLite.OrmLiteConnectionFactory.OpenDbConnection() in C:\BuildAgent\work\27e4cc16641be8c0\src\ServiceStack.OrmLite\OrmLiteConnectionFactory.cs:line 95\r\n   at ServiceStack.ServiceStackHost.GetDbConnection(IRequest req) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack\ServiceStackHost.Runtime.cs:line 691\r\n   at ServiceStack.AutoQuery.GetDb(Type type, IRequest req) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack.Server\AutoQueryFeature.cs:line 598\r\n   at ServiceStack.AutoQuery.CreateQuery[From](IQueryDb`1 dto, Dictionary`2 dynamicParams, IRequest req) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack.Server\AutoQueryFeature.cs:line 608\r\n   at IDOE.SecurityPortal.Api.ServiceInterface.OrganizationUserStaffTypeService.Get(QueryOrganizationUserStaffTypes query) in E:\source\repos\Azure - Security Portal\src\IDOE.SecurityPortal\IDOE.SecurityPortal.Api.ServiceInterface\OrganizationUserStaffTypeService.cs:line 47\r\n   at ServiceStack.Host.ServiceRunner`1.<ExecuteAsync>d__15.MoveNext() in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack\Host\ServiceRunner.cs:line 133

在startup.cs

中注册数据库连接
    var dbFacotry = container.Resolve<IDbConnectionFactory>();
    dbFacotry.RegisterConnection("SecPortal", AppSettings.Get<string>("SQLSERVER-SECPORTAL-CONNECTIONSTRING"), SqlServer2017Dialect.Provider);
    dbFacotry.RegisterConnection("EdfiMdm", AppSettings.Get<string>("SQLSERVER-EDFIMDM-CONNECTIONSTRING"), SqlServer2017Dialect.Provider);

    Plugins.Add(new AutoQueryFeature { IncludeTotal = true });

自动查询定义

[Authenticate]
[RequiredClaim("scope", "secprtl-read")]
[Route("/files", Verbs = "GET")]
[ConnectionInfo(NamedConnection = "SecPortal")]
public class QueryFiles : QueryDb<Types.File>
{
    [QueryDbField(Field = "Id", Template = "({Value} IS NULL OR {Field} = {Value})")]
    public int? Id { get; set; }

    [QueryDbField(Field = "FileName", Template = "({Value} IS NULL OR UPPER({Field}) LIKE UPPER({Value}))", ValueFormat = "%{0}%")]
    public string FileName { get; set; }

    [QueryDbField(Field = "UserId", Template = "({Value} IS NULL OR UPPER({Field}) LIKE UPPER({Value}))", ValueFormat = "%{0}%")]
    public string UserId { get; set; }

    [QueryDbField(Field = "StateOrganizationId", Template = "({Value} IS NULL OR UPPER({Field}) LIKE UPPER({Value}))", ValueFormat = "%{0}%")]
    public string StateOrganizationId { get; set; }

    [QueryDbField(Field = "Notes", Template = "({Value} IS NULL OR UPPER({Field}) LIKE UPPER({Value}))", ValueFormat = "%{0}%")]
    public string Notes { get; set; }
}

调用服务的代码

public class ContactService : Service
{

    public ContactService()
    {
    }

    public async Task<object> Post(PostContact request)
    {
        try
        {
            var files = base.Gateway.Send(new QueryFiles() { });

            return new Contact() { Name = request.Name };
        }
        catch (Exception ex)
        {
            throw ex;
        }

    }


}

自定义服务网关

public class CustomServiceGatewayFactory : ServiceGatewayFactoryBase
{

    private IRequest request;

    public override IServiceGateway GetServiceGateway(IRequest request)
    {
        this.request = request;
        return base.GetServiceGateway(request);
    }

    public override IServiceGateway GetGateway(Type requestType)
    {
        var isLocal = HostContext.Metadata.RequestTypes.Contains(requestType);

        if (isLocal)
        {
            return base.localGateway;
        }
        else
        {
            return new JsonServiceClient("https://localhost:6001")
            {
                BearerToken = request.GetBearerToken()
            };
        }
    }

}

startup.cs

中的自定义服务网关注册
container.Register<IServiceGatewayFactory>(x => new CustomServiceGatewayFactory()).ReusedWithin(ReuseScope.None);

在服务 class 中进行的呼叫是本地呼叫。调用使用自动查询的外部服务工作得很好。我也可以直接调用本地服务没有问题。


我在服务接口中创建了自定义自动查询方法,我注意到 request.items 数组中未填充数据库连接信息。所以我手动将该信息添加到请求中,并且它按预期工作。所以不知何故,在我的设置中,本地调用的自动查询操作,数据库连接信息没有被添加到请求对象中。

Request Filter Attributes[ConnectionInfo] 类似,仅适用于 HTTP 请求,不适用于内部服务网关请求。

连接信息未配置,因为它未在调用进程内服务网关的 PostContact 服务请求 DTO 上注释。

您可以将 [ConnectionInfo] QueryFiles AutoQuery 请求 DTO 附加到当前请求:

public async Task<object> Post(PostContact request)
{
    try
    {
        typeof(QueryFiles).FirstAttribute<ConnectionInfoAttribute>()
            .Execute(Request,Response,request);

        var files = base.Gateway.Send(new QueryFiles() { });

        return new Contact() { Name = request.Name };
    }
    catch (Exception ex)
    {
        throw ex;
    }
}