ServiceStack:我可以“展开”帖子主体的结构吗?
我有一个采用URL路径参数的POST端点,然后主体是提交的DTO列表。
所以现在请求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; }
}
服务方法如下所示:
public class SomeService : Service
{
public SomeResponse Post(SomeRequest request)
{
}
}
如果通过JSON编码,客户端将不得不通过这种方式编码POST主体:
{
"Entries":
[
{
"id": 1
"type": 42
"value": "Y"
},
...
]
}
这是多余的,我希望客户端提交像这样的数据:
[
{
"id": 1
"type": 42
"value": "Y"
},
...
]
如果我的请求DTO只是List<SomeEntry>
,情况就会List<SomeEntry>
我的问题是:有没有办法通过这种方式“扁平化”请求? 或者将请求的一个属性指定为消息主体的根? 即也许:
[Route("/prefix/{Param1}", "POST")]
public class SomeRequest
{
public string Param1 { get; set; }
[MessageBody]
public List<SomeEntry> Entries { get; set; }
}
这在ServiceStack中可以以任何方式进行操作吗?
我能够通过继承List<T>
来完成这项工作:
[Route("/prefix/{Param1}", "POST")]
public class SomeRequest : List<SomeEntry>
{
public string Param1 { get; set; }
}
然后你可以发送这样的请求:
POST /prefix/someParameterValue
Content-Type: application/json
[ { "ID": 1, "Type": 2, "Value": "X" }, ... ]
但是如果你在设计中有任何选择,我不会推荐这个。 从以下几个原因开始:
[ ]
,会导致一个带有RequestBindingException
的400
状态码 好的,我设法实现了这一点。 不是最漂亮的解决方案,但现在会做。
我为JSON封装了内容类型过滤器:
var serz = ContentTypeFilters.GetResponseSerializer("application/json");
var deserz = ContentTypeFilters.GetStreamDeserializer("application/json");
ContentTypeFilters.Register("application/json", serz, (type, stream) => MessageBodyPropertyFilter(type, stream, deserz));
然后,自定义解串器看起来像这样:
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
在初始化后通过扫描请求DTO并寻找特定属性来填充,如我原始问题中的示例。
上一篇: ServiceStack: Can I "Flatten" the structure of the post body?
下一篇: how to pass in paramters to a post request using the servicestack json client