场景如下所示:
我有这个web,它将处理各种各样的支付网关,我希望所有这些都有相同的端点。
所以,我想要的是得到这样的json数据:
{
"OperationId":"N0004",
"Generic_Object_That_Will_Change_According_ToThe_GateWay":
{
"Sale_id":1000,
"CodUser":"1000040",
"Email":"teste@teste.com"
}
}或者这个,对于其他的支付网关
{
"OperationId":"N044444",
"Generic_Object_That_Will_Change_According_ToThe_GateWay":
{
"Token":1000,
"UserSettings":{
id: "4563345",
name: "Average Joe"
}
}
}我想要做的是在每个支付网关(paypal或其他一些)的特定对象中转换这个"Generic_Object_That_Will_Change_According_ToThe_GateWay“,因为每一个都是完全不同的,但我不希望这影响客户机调用这个API的方式--我希望它尽可能灵活,以一种只需在这个Generic_Object_That_Will_Change_According_ToThe_GateWay,中传递任何数据的方式。然后,我将把它转换成适当的对象,然后调用另一个端点(如aggragate微服务设计),传递这个新创建的对象。
到目前为止,我的想法是创建具有如下泛型属性的类
public class Payment<Gateway>
{
public int OperationId{ get; set; }
public Gateway paymentGateWay{ get; set; }
}并且这个属性paymentGateWay可以根据可用的支付网关输入。
然后,也许我可以将API方法中的数据作为对象,并执行必要的强制转换。
[Route("api/payment")]
[HttpPost]
public string Compra(Object payment) {但是,老实说,我不知道我是不是走对了路。
我已经知道,我不能在web端点中有一个泛型方法,那么考虑到json数据的一部分是灵活的/泛型的,并且可能被转换到几个不同的对象,那么在我的端点中获取这些数据的正确方法是什么?
总之,我想处理可以反序列化为几个不同已知对象的json数据,但我不希望在API中有一个不同的方法来处理每个可能的数据场景。
发布于 2017-10-21 21:32:26
如果您想在webapi中使用泛型方法,则必须使用JObject,如下所示
public void Post([FromBody] JObject testJObject)
{
//here you have to do some additional work in order to parse and get it working for generic entity
}此外,您还可以对接收到的任何请求使用架构验证器,并使用工厂模式来创建正确的对象
这里有一个例子
var json =
" {\"OperationId\":\"N0004\",\"Generic_Object_That_Will_Change_According_ToThe_GateWay\":{\"Sale_id\":1000,\"CodUser\":\"1000040\"}}";
JsonSchema paypalschema = new JsonSchema();
paypalschema.Type = JsonSchemaType.Object;
paypalschema.Properties = new Dictionary<string, JsonSchema>
{
{"OperationId", new JsonSchema {Type = JsonSchemaType.String}},
{
"Generic_Object_That_Will_Change_According_ToThe_GateWay",
new JsonSchema {Type = JsonSchemaType.Object,Properties = new Dictionary<string, JsonSchema>
{
{"Sale_id", new JsonSchema {Type = JsonSchemaType.Integer}},
{"CodUser", new JsonSchema {Type = JsonSchemaType.String}},
}}
}
};
JObject requestObject = JObject.Parse( json);
bool valid = requestObject.IsValid(paypalschema);
if (valid)
{
//create your GatewayObject here
}
//else check another gateway object 发布于 2017-10-21 21:32:07
考虑使用JObject或String作为输入(然后转换为JObject)。然后,您可以做一些类型或数据检查之前,铸造。Here's an example shows how they use a pre-defined 'type' value provided,但取而代之的是,您可以在JObject中查找每个唯一提供者的有效负载的“部件”,以确定使用哪种类型。
发布于 2017-10-22 00:25:39
可以有一个泛型控制器来实现继承泛型控制器的方法和实例-控制器:
// I'll rename Gateway to TGateway according to the fact, that it is a generic Type parameter.
public class Payment<TGateway>
{
public int OperationId{ get; set; }
public TGateway paymentGateWay{ get; set; }
}GenericController:
// Don't add a RouteAttribute to this Controller.
public class GenericController<TGateway>: ApiController
{
// The implementation of the method. No RouteAttribute.
[HttpPost]
public string Compra(Payment<TGateway> payment) {...}
}InstanceController:
// No need to override the method. RouteAttribute.
[Route("api/payment/"+typeof(AGateway).Name)]
public class AGatewayController : GenericController<AGateway>
{}https://stackoverflow.com/questions/46868177
复制相似问题