此解决方案适用于需要打包和转换许多 DTO 的情况,并且高度可重用,无需更改现有 DTO。
您可以通过重写处理准备发送请求的方法来转换JsonServiceClient 的请求。这意味着实现您自己的扩展 JsonServiceClient如下所示。
如果您想对所有动词执行此操作,则覆盖它的 Send<TResponse> 方法(否则,如果它仅适用于 POST,则取消注释掉注释掉的代码,并删除 Send 方法) .
public class MyJsonServiceClient : JsonServiceClient
{
public Dictionary<Type, Func<object, object>> DtoConverters = new Dictionary<Type, Func<object, object>>();
public MyJsonServiceClient() {}
public MyJsonServiceClient(string baseUri) : base(baseUri) {}
public MyJsonServiceClient(string syncReplyBaseUri, string asyncOneWayBaseUri) : base(syncReplyBaseUri, asyncOneWayBaseUri) {}
public override TResponse Send<TResponse>(object request)
{
return base.Send<TResponse>(ConvertRequest(request));
}
public override TResponse Send<TResponse>(string httpMethod, string relativeOrAbsoluteUrl, object request)
{
return base.Send<TResponse>(httpMethod, relativeOrAbsoluteUrl, ConvertRequest(request));
}
/*
public override TResponse Post<TResponse>(string relativeOrAbsoluteUrl, object requestDto)
{
return base.Post(relativeOrAbsoluteUrl, ConvertRequest(requestDto));
}
*/
object ConvertRequest(object request)
{
Type dtoType = request.GetType();
return (DtoConverters.ContainsKey(dtoType)) ? DtoConverters[dtoType](request) : request;
}
}
用法:
所以给定这个 DTO:
[Route("/test", "POST")]
public class TicketRequest : IReturnVoid
{
public string CartId { get; set; }
public string PriceId { get; set; }
}
您只需添加转换器:
var client = new MyJsonServiceClient("http://localhost:9000");
// Simple converter for TicketRequest
client.DtoConverters.Add(typeof(TicketRequest), dto => {
var d = (TicketRequest)dto;
return new {
data = new {
CartId = d.CartId.ToInt(),
PriceId = d.PriceId.ToInt()
}
};
});
client.Post(new TicketRequest { CartId = "123", PriceId = "456" });