MVC请求干扰对AutoQuery-enabled ServiceStack API的调用

本文关键字:API 调用 ServiceStack AutoQuery-enabled 请求 干扰 MVC | 更新日期: 2023-09-27 18:26:22

我有一个MVC解决方案,其中包含ServiceStack API和对API服务进行调用的MVC UI。其中一些服务是AutoQuery GET端点,我遇到了一个问题,ServiceStack服务会在我调用这些服务时获取已发布的表单值或不相关的查询字符串值并抛出参数错误。

我已经尝试了多种呼叫服务的方式:

using (var fooSvc = new HostContext.ResolveService<FooService>(HttpContext))
{
    var foos = (QueryResponse<Foo>)fooSvc.Get(new Foos());
    // Do stuff here
}

没有骰子。张贴的表单值把它搞砸了,我在我的服务中的这行收到了一个System.FormatException,上面写着Input string was not in a correct format

var q = AutoQuery.CreateQuery(request, Request.GetRequestParams());

所以我尝试了:

var foos = (QueryResponse<Foo>)HostContext.ServiceController.Execute(new Foos());

在这种情况下,我得到一个System.NotImplementedException,说它找不到Post(Foos)Any(Foos)(有问题的调用是GET)。

我确信我只是错过了一些东西。米兹,又有人救我了吗?

编辑:我亲手输入了代码。。。当我指的是CCD_ 9时,初始块具有CCD_。。。

编辑2:这是我的自动查询服务的一般结构。这些都是服务上的GET,因为这些端点还需要支持POST来创建资源。例如,我的URI可能位于http:/service.com/api/users,并且希望能够使用AutoQuery或POSTGET以创建新用户。

[Authenticate]
public class UsersService : Service
{
    public IAutoQuery AutoQuery { get; set; }
    public object Get(Users request)
    {
        var q = AutoQuery.CreateQuery(request, Request.GetRequestParams());
        // Here I add some other conditions to the query object to filter results based on the user's role, etc.
        return AutoQuery.Execute(request, q);
    }
    [RequiredRole("Admin")]
    public object Post(CreateUser request)
    {
        var user = request.ConvertTo<User>();
        Db.Save(user);
        return user;
    }
}

MVC请求干扰对AutoQuery-enabled ServiceStack API的调用

当您调用服务时,您只是直接在目标实例上调用一个方法。该方法返回什么?它不太可能是AutoQuery<Foo>,因为它不是ServiceStack:中的有效类型

var foos = (AutoQuery<Foo>)fooSvc.Get(new Foos());

如果您得到FormatException,请检查导致它的QueryString参数。Request中的某些内容与AutoQuery字段不兼容。

您是否自己创建了该方法,因为AutoQuery使用Any方法生成服务,以便任何谓词都可以调用它。如果是自定义服务,请将其更改为Any

否则,您可以使用当前HTTP请求执行该方法:

var foos = (QueryResponse<Foo>)HostContext.ServiceController
    .Execute(new Foos(), HttpContext.ToRequest());

您还可以覆盖执行的谓词:

var req = HttpContext.ToRequest();
req.Items[Keywords.InvokeVerb] = "GET";
var foos = (QueryResponse<Foo>)HostContext.ServiceController
    .Execute(new Foos(), req);

自定义自动查询实现

如果您在尝试转发请求时有冲突的字段,我会将它们更改为使用与自动查询请求不冲突的字段。但是,如果您仍然想继续使用冲突字段,您可以创建自定义自动查询实现,将其从自动查询服务中删除,例如:

public class UsersService : Service
{
    public IAutoQuery AutoQuery { get; set; }
    public object Any(Users request)
    {
        Dictionary<string, string> args = Request.GetRequestParams();
        args.Remove("OrganizationId");// E.g remove conflicted fields
        var q = AutoQuery.CreateQuery(request, args);
        return AutoQuery.Execute(request, q);
    }
}