Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在WEBAPI方法中处理泛型对象的正确方法是什么?_C#_.net_Generics_Asp.net Web Api - Fatal编程技术网

C# 在WEBAPI方法中处理泛型对象的正确方法是什么?

C# 在WEBAPI方法中处理泛型对象的正确方法是什么?,c#,.net,generics,asp.net-web-api,C#,.net,Generics,Asp.net Web Api,场景是这样的: 我有这个web api,它将处理各种支付网关,我希望所有这些都有相同的端点 所以,我想得到的是一些json数据,如下所示: { "OperationId":"N0004", "Generic_Object_That_Will_Change_According_ToThe_GateWay": { "Sale_id":1000, "CodUser":"1000040", "Email":"teste@teste.

场景是这样的:

我有这个web api,它将处理各种支付网关,我希望所有这些都有相同的端点

所以,我想得到的是一些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或其他)的特定对象中转换这个“通用对象”,它将根据网关进行更改,因为每个对象完全不同,但我不想影响客户端调用此API的方式-我希望它尽可能灵活,在某种程度上,你只需要将这个通用对象中的任何数据传递给网关,然后我将把它转换到合适的对象,然后调用另一个端点(比如一个Agragate微服务设计)传递这个新创建的对象

到目前为止,我的想法是创建一个具有如下泛型属性的类

 public class Payment<Gateway>
    {
        public int OperationId{ get; set; }
        public Gateway paymentGateWay{ get; set; }
    }
但是,老实说,我不知道我的方式是否正确

我已经知道,我不能在web api端点中使用泛型方法——因此,考虑到此json数据的一部分是灵活/泛型的,并且可能会转换为几个不同的对象,那么在我的端点中获取此数据的正确方法是什么呢


总之,我想处理可以反序列化为几个不同已知对象的json数据,但我不想在API中使用不同的方法来处理每个可能的数据场景。

考虑使用JObject或String作为输入(然后转换为JObject)然后您可以在强制转换之前进行一些类型或数据检查,但作为替代,您可以在JObject中查找每个唯一提供者有效负载的“部分”,以确定使用哪种类型。

如果您想在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 
var-json=
“{\”操作id\”:“N0004\”,“将根据网关更改的通用对象”:“{\”销售id\”:1000,\”代码用户\“:\”1000040\”}”;
JsonSchema paypalschema=新JsonSchema();
paypalschema.Type=JsonSchemaType.Object;
paypalschema.Properties=新字典
{
{“OperationId”,新的JsonSchema{Type=JsonSchemaType.String},
{
“将根据网关更改的通用对象”,
新建JsonSchema{Type=JsonSchemaType.Object,属性=new Dictionary
{
{“Sale_id”,新的JsonSchema{Type=JsonSchemaType.Integer},
{“CodUser”,新的JsonSchema{Type=JsonSchemaType.String},
}}                   
}
};
JObject requestObject=JObject.Parse(json);
bool valid=requestObject.IsValid(paypalschema);
如果(有效)
{
//在此处创建您的网关对象
}
//否则请检查另一个网关对象

您可以使用通用控制器来实现方法和实例控制器,它们继承通用控制器:

// 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; }
    }
// 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) {...}
}
// No need to override the method. RouteAttribute.
[Route("api/payment/"+typeof(AGateway).Name)]
public class AGatewayController : GenericController<AGateway>
{}
//我将把Gateway重命名为TGateway,因为它是一个泛型类型参数。
公共类支付
{
公共int操作ID{get;set;}
公用TGateway付费网关{get;set;}
}
通用控制器:

// 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; }
    }
// 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) {...}
}
// No need to override the method. RouteAttribute.
[Route("api/payment/"+typeof(AGateway).Name)]
public class AGatewayController : GenericController<AGateway>
{}
//不要将RouteAttribute添加到此控制器。
公共类泛型控制器:ApiController
{
//方法的实现。无RouteAttribute。
[HttpPost]
公共字符串Compra(付款){…}
}
InstanceController:

// 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; }
    }
// 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) {...}
}
// No need to override the method. RouteAttribute.
[Route("api/payment/"+typeof(AGateway).Name)]
public class AGatewayController : GenericController<AGateway>
{}
//无需重写该方法。路线属性。
[路线(“api/付款/”+类型(AGateway).Name]
公共类AGatewayController:GenericController
{}

您是否设法解决了问题?