我有以下请求DTO:
[Route("/processresults")]
public class FindProcessResults : QueryBase<ProcessResult, ProcessResultDto> {}
ProcessResult
有一个名为Id
(Int32)的属性。我的数据库中有两个ProcessResults
,Id 1和2。
当我对/ processresults执行GET时?Id = 1我返回了一个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请求正在尝试反序列化为<From> dto
。 From
类型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"....
答案 0 :(得分:0)
您应该强烈考虑使用GET
请求来使用AutoQuery服务,这些服务更适合使用HTTP Verb,它也更易于缓存和内省。
如果您想POST
并且不想使用HTML表单POST(即x-www-form-urlencoded
内容类型),则需要通过将参数添加到请求来形式化参数DTO:
[Route("/processresults")]
public class FindProcessResults : QueryBase<ProcessResult, ProcessResultDto>
{
public int Id { get; set; }
}
否则,它会尝试将JSON反序列化为空DTO,其中忽略任何不存在的属性。