AutoPopulate 属性不适用于 AutoQuery DTO
AutoPopulate attribute not working on AutoQuery DTO
我正在尝试使用新的 AutoPopulate 属性,但我在理解新的 AutoQuery 功能时遇到了一些困难。
为了测试它,我的目标是替换这个服务,它是一个标准的 AutoQuery 端点,但它也通过登录的用户 ID 进行过滤。我想替换它,以便它完全适用于模型定义。
public class DevExtremeService : ServiceBase
{
public IAutoQueryDb AutoQuery { get; set; }
public QueryResponse<DeWatchedUrlResponse> Any(WatchedUrlDevExRequest request)
{
var q = AutoQuery.CreateDevXQuery(request, Request.GetRequestParams(), Request);
q.Where(x => x.UserAuthCustomId == GetUserId());
var response = AutoQuery.Execute(request, q, base.Request);
return response;
}
}
[Route("/de/watched-urls")]
public class WatchedUrlDevExRequest : QueryDb<WatchedUrlRecord, DeWatchedUrlResponse>
{
}
所以我删除了服务并将模型更新为:
[ValidateIsAuthenticated]
[AutoPopulate(nameof(WatchedUrlDevExRequest.UserAuthCustomId), Eval = "userAuthId")]
[Route("/de/watched-urls")]
public class WatchedUrlDevExRequest : QueryDb<WatchedUrlRecord, DeWatchedUrlResponse>
{
public long UserAuthCustomId { get; set; }
}
我阅读发行说明后的理解是 userAuthId
是在默认添加的 AutoQuery #script 上下文中声明的变量。
我尝试了几种不同的变体,但无法填充 属性。这些文档似乎侧重于审计历史和多租户,但实际上我只是在寻找一种快速创建端点的方法。
我有两个主要问题:
- 为什么自动填充在此 属性 上不起作用?
- 我在哪里可以看到默认的 #script 定义,这样我就可以看到
userAuthId
之类的东西是如何定义的,并且更好地了解如何添加我自己的东西?
编辑
我重新阅读了文档,我猜这只在将数据写入数据库时有效。我真的很喜欢能够通过属性将#script 应用于请求模型的概念。这可能吗?
AutoQuery CRUD 的 [AutoPopulate] 属性最初仅在执行 CRUD 操作时填充 AutoQuery CRUD 的数据模型,例如插入、更新或删除实体。
为了确保仅查询 returns 用户记录,建议改为 use an AutoFilter,这会确保查询始终应用于数据模型,这符合预期,例如:
[ValidateIsAuthenticated]
[Route("/de/watched-urls")]
[AutoFilter(QueryTerm.Ensure, nameof(WatchedUrlRecord.UserAuthCustomId),
Eval = "userAuthId")]
public class WatchedUrlDevExRequest : QueryDb<WatchedUrlRecord, DeWatchedUrlResponse>
{
}
然而,正如我所看到的,这是一个有用的功能,我还刚刚在 this commit 中的查询 DTO 上添加了对 [AutoPopulate]
和 [AutoMap]
属性的支持,您的 AutoQuery DTO 可以作为预期它填充请求 DTO 的位置 属性:
[ValidateIsAuthenticated]
[AutoPopulate(nameof(WatchedUrlDevExRequest.UserAuthCustomId), Eval = "userAuthId")]
[Route("/de/watched-urls")]
public class WatchedUrlDevExRequest : QueryDb<WatchedUrlRecord, DeWatchedUrlResponse>
{
public long UserAuthCustomId { get; set; }
}
此更改适用于现在 available on MyGet 的 v5.10.3。
填充 AutoQuery 的 Request DTO 的另一种方法,您可以拥有像您一样的自定义 AutoQuery 实现,一个可扩展 Query Filter or custom base class or I'd personally go with a Global Request Filter,它使用共享接口更新所有 Request DTO,例如:
GlobalRequestFilters.Add((req, res, dto) => {
if (dto is IHasUserAuthCustomId authDto)
{
var session = req.GetSession();
if (session.IsAuthenticated)
authDto.UserAuthCustomId = session.UserAuthId;
}
});
或者您可以将此逻辑包装在 Request Filter Attribute 中,并以这种方式将行为应用于请求 DTO。
注意:userAuthId
是 ServiceStack #Script method 即 returns 当前已验证的用户 ID。
我正在尝试使用新的 AutoPopulate 属性,但我在理解新的 AutoQuery 功能时遇到了一些困难。
为了测试它,我的目标是替换这个服务,它是一个标准的 AutoQuery 端点,但它也通过登录的用户 ID 进行过滤。我想替换它,以便它完全适用于模型定义。
public class DevExtremeService : ServiceBase
{
public IAutoQueryDb AutoQuery { get; set; }
public QueryResponse<DeWatchedUrlResponse> Any(WatchedUrlDevExRequest request)
{
var q = AutoQuery.CreateDevXQuery(request, Request.GetRequestParams(), Request);
q.Where(x => x.UserAuthCustomId == GetUserId());
var response = AutoQuery.Execute(request, q, base.Request);
return response;
}
}
[Route("/de/watched-urls")]
public class WatchedUrlDevExRequest : QueryDb<WatchedUrlRecord, DeWatchedUrlResponse>
{
}
所以我删除了服务并将模型更新为:
[ValidateIsAuthenticated]
[AutoPopulate(nameof(WatchedUrlDevExRequest.UserAuthCustomId), Eval = "userAuthId")]
[Route("/de/watched-urls")]
public class WatchedUrlDevExRequest : QueryDb<WatchedUrlRecord, DeWatchedUrlResponse>
{
public long UserAuthCustomId { get; set; }
}
我阅读发行说明后的理解是 userAuthId
是在默认添加的 AutoQuery #script 上下文中声明的变量。
我尝试了几种不同的变体,但无法填充 属性。这些文档似乎侧重于审计历史和多租户,但实际上我只是在寻找一种快速创建端点的方法。
我有两个主要问题:
- 为什么自动填充在此 属性 上不起作用?
- 我在哪里可以看到默认的 #script 定义,这样我就可以看到
userAuthId
之类的东西是如何定义的,并且更好地了解如何添加我自己的东西?
编辑
我重新阅读了文档,我猜这只在将数据写入数据库时有效。我真的很喜欢能够通过属性将#script 应用于请求模型的概念。这可能吗?
AutoQuery CRUD 的 [AutoPopulate] 属性最初仅在执行 CRUD 操作时填充 AutoQuery CRUD 的数据模型,例如插入、更新或删除实体。
为了确保仅查询 returns 用户记录,建议改为 use an AutoFilter,这会确保查询始终应用于数据模型,这符合预期,例如:
[ValidateIsAuthenticated]
[Route("/de/watched-urls")]
[AutoFilter(QueryTerm.Ensure, nameof(WatchedUrlRecord.UserAuthCustomId),
Eval = "userAuthId")]
public class WatchedUrlDevExRequest : QueryDb<WatchedUrlRecord, DeWatchedUrlResponse>
{
}
然而,正如我所看到的,这是一个有用的功能,我还刚刚在 this commit 中的查询 DTO 上添加了对 [AutoPopulate]
和 [AutoMap]
属性的支持,您的 AutoQuery DTO 可以作为预期它填充请求 DTO 的位置 属性:
[ValidateIsAuthenticated]
[AutoPopulate(nameof(WatchedUrlDevExRequest.UserAuthCustomId), Eval = "userAuthId")]
[Route("/de/watched-urls")]
public class WatchedUrlDevExRequest : QueryDb<WatchedUrlRecord, DeWatchedUrlResponse>
{
public long UserAuthCustomId { get; set; }
}
此更改适用于现在 available on MyGet 的 v5.10.3。
填充 AutoQuery 的 Request DTO 的另一种方法,您可以拥有像您一样的自定义 AutoQuery 实现,一个可扩展 Query Filter or custom base class or I'd personally go with a Global Request Filter,它使用共享接口更新所有 Request DTO,例如:
GlobalRequestFilters.Add((req, res, dto) => {
if (dto is IHasUserAuthCustomId authDto)
{
var session = req.GetSession();
if (session.IsAuthenticated)
authDto.UserAuthCustomId = session.UserAuthId;
}
});
或者您可以将此逻辑包装在 Request Filter Attribute 中,并以这种方式将行为应用于请求 DTO。
注意:userAuthId
是 ServiceStack #Script method 即 returns 当前已验证的用户 ID。