[英]ServiceStack: Can I “Flatten” the structure of the post body?
I have a POST endpoint that takes a URL path param and then the body is a list of submitted DTOs. 我有一个采用URL路径参数的POST端点,然后该正文是已提交DTO的列表。
So right now the request DTO looks something along the lines of: 因此,现在请求DTO看起来类似于:
[Route("/prefix/{Param1}", "POST")]
public class SomeRequest
{
public string Param1 { get; set; }
public List<SomeEntry> Entries { get; set; }
}
public class SomeEntry
{
public int ID { get; set; }
public int Type { get; set; }
public string Value { get; set; }
}
And the service method looks something like: 服务方法类似于:
public class SomeService : Service
{
public SomeResponse Post(SomeRequest request)
{
}
}
If encoded via JSON, the client would have to encode the POST body this way: 如果通过JSON编码,则客户端必须以这种方式编码POST正文:
{
"Entries":
[
{
"id": 1
"type": 42
"value": "Y"
},
...
]
}
This is redundant, I would like the client to submit the data like this: 这是多余的,我希望客户端提交这样的数据:
[
{
"id": 1
"type": 42
"value": "Y"
},
...
]
Which would have been the case if my request DTO was simply List<SomeEntry>
如果我的请求DTO只是
List<SomeEntry>
会是这种情况
My questions is: is there a way to "flatten" the request this way? 我的问题是:是否可以通过这种方式“平整”请求? Or designate one property of the request as the root of the message body?
还是将请求的一个属性指定为消息正文的根? ie perhaps:
即也许:
[Route("/prefix/{Param1}", "POST")]
public class SomeRequest
{
public string Param1 { get; set; }
[MessageBody]
public List<SomeEntry> Entries { get; set; }
}
Is this doable in any way in ServiceStack? 这在ServiceStack中是否可以实现?
I was able to sort of get this to sort of work by subclassing List<T>
: 我可以通过将
List<T>
子类化来解决这个问题:
[Route("/prefix/{Param1}", "POST")]
public class SomeRequest : List<SomeEntry>
{
public string Param1 { get; set; }
}
Then you can send a request like this: 然后,您可以发送如下请求:
POST /prefix/someParameterValue
Content-Type: application/json
[ { "ID": 1, "Type": 2, "Value": "X" }, ... ]
But if you have any choice in the design, I wouldn't recommend this. 但是,如果您在设计中有任何选择,我将不建议这样做。 Here's a couple of reasons to start with:
从以下几个原因开始:
[ ]
in JSON, is resulting in a 400
status code with RequestBindingException
[ ]
,导致带有RequestBindingException
的400
状态代码 OK I've managed to achieve this. 好的,我已经设法做到这一点。 Not the prettiest solution but will do for now.
不是最漂亮的解决方案,但现在可以使用。
I wrapped the content type filter for JSON: 我包装了JSON的内容类型过滤器:
var serz = ContentTypeFilters.GetResponseSerializer("application/json");
var deserz = ContentTypeFilters.GetStreamDeserializer("application/json");
ContentTypeFilters.Register("application/json", serz, (type, stream) => MessageBodyPropertyFilter(type, stream, deserz));
Then the custom deserializer looks like this: 然后,自定义解串器如下所示:
private object MessageBodyPropertyFilter(Type type, Stream stream, StreamDeserializerDelegate original)
{
PropertyInfo prop;
if (_messageBodyPropertyMap.TryGetValue(type, out prop))
{
var requestDto = type.CreateInstance();
prop.SetValue(requestDto, original(prop.PropertyType, stream), null);
return requestDto;
}
else
{
return original(type, stream);
}
}
_messageBodyPropertyMap
is populated after init by scanning the request DTOs and looking for a certain attribute, as in the example in my original question. 初始化后,通过扫描请求DTO并查找特定属性来填充
_messageBodyPropertyMap
,如我原始问题中的示例所示。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.