【问题标题】:ServiceStack AutoQuery, Implicit/Explicit QueriesServiceStack 自动查询、隐式/显式查询
【发布时间】:2014-11-04 05:44:03
【问题描述】:

我有以下请求 DTO:

[Route("/processresults")]
public class FindProcessResults : QueryBase<ProcessResult, ProcessResultDto>  {}

ProcessResult 有一个名为 Id (Int32) 的属性。我的数据库中有两个ProcessResults,ID 1 和 2。

当我对 /processresults?Id=1 执行 GET 时,我得到一个 ProcessResult 返回。太好了。

但是,当我发布此 JSON 时,我得到两个 ProcessResults 返回。查询未执行。当我将属性 Id 添加到 FindProcessResults 时,JSON 调用确实有效,但是我没有将 EnableUntypedQueries 设置为 false。

PostData: {"Id":"1"}

这可能是什么问题?

奖励积分,如果我使用表单数据创建 POST,我会收到以下异常:

{
   ResponseStatus: {
     ErrorCode: "RequestBindingException",
     Message: "Unable to bind request",
     StackTrace: " at ServiceStack.Host.RestHandler.CreateRequest(IRequest httpReq, IRestPath restPath)\ \ at ServiceStack.Host.RestHandler.ProcessRequestAsync(IRequest httpReq, IResponse httpRes, String operationName)"
   }
}

但是,如果我对 x-www-form-urlencoded 执行相同的操作(发布),则查询会按预期工作(返回单个结果)。

结论:虽然我可以通过将我希望通过 (Id) 查询的参数添加到类型化请求中来解决此问题,但这违背了我想要实现的目的,即我的数据存储的通用查询机制。 GET 版本请求的功能已经存在。

我认为这与 AutoQueryServiceBase 的实现有关:

        public virtual object Exec<From>(IQuery<From> dto)
        {
            SqlExpression<From> q;
            using (Profiler.Current.Step("AutoQuery.CreateQuery"))
            {
                q = AutoQuery.CreateQuery(dto, Request.GetRequestParams());
            }
            using (Profiler.Current.Step("AutoQuery.Execute"))
            {
                return AutoQuery.Execute(dto, q);
            }
        }

这是使用Request.GetRequestParams(),它将从查询字符串或表单参数返回参数,而JSON 请求正试图反序列化为&lt;From&gt; dtoFrom 类型 FindProcessResults 没有 Id 属性,因此不会填充并传递给查询。

请求的 HTTP 请求/响应:

请求

POST /processresults HTTP/1.1
Host: localocl
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: 36d4b37e-0407-a9b3-f2f2-5b024d7faf7f

{"Id":1}

回应

Cache-Control → private
Content-Length → 1580
Content-Type → application/json; charset=utf-8
Date → Mon, 03 Nov 2014 21:20:43 GMT
Server → Microsoft-IIS/8.5
Vary → Accept
X-AspNet-Version → 4.0.30319
X-Powered-By → ServiceStack/4.033 Win32NT/.NET, ASP.NET

{"Offset":0,"Total":2,"Results"....

【问题讨论】:

  • 能否请您发布使用 Fiddler 或 WebInspector 等失败的查询的完整 HTTP 请求/响应。
  • 感谢您的帮助@mythz 我已附上请求/响应。

标签: servicestack ormlite-servicestack


【解决方案1】:

您应该强烈考虑使用 GET 请求来消费 AutoQuery 服务,这更适合使用 HTTP 动词,也更可缓存和内省。

如果您想POST 并且不想使用 HTML 表单 POST(即 x-www-form-urlencoded Content-Type),则需要通过将参数添加到请求 DTO 来形式化参数:

[Route("/processresults")]
public class FindProcessResults : QueryBase<ProcessResult, ProcessResultDto>  
{
    public int Id { get; set; }
}

否则它将尝试将 JSON 反序列化为一个空的 DTO,其中任何不存在的属性都将被忽略。

【讨论】:

  • 感谢您的回复。因此,反序列化到 Request DTO 阻止了它的工作。我意识到 GET 是一个更好的动词,但是它很容易创建一个 javascript 对象并将其发布为 JSON。我将不得不研究在 javascript 中创建查询字符串的更简单方法。感谢您的回复时间和精力:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-27
相关资源
最近更新 更多