Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.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# 用于继承/类型识别的自定义模型绑定器_C#_Asp.net Core - Fatal编程技术网

C# 用于继承/类型识别的自定义模型绑定器

C# 用于继承/类型识别的自定义模型绑定器,c#,asp.net-core,C#,Asp.net Core,抱歉,如果这个问题已经被问了一百万次了,但我似乎无法在谷歌上找到解决方案 在ASP.NETCore中,是否可以编写一个自定义模型绑定器或类似的东西,使我能够在web API中获得一些继承支持 基本上我有一门课,比如: public class Order { public Guid Id { get; set; } public PaymentContainer PaymentParameters { get; set; } } 还有一个容器类,比如 public class Pa

抱歉,如果这个问题已经被问了一百万次了,但我似乎无法在谷歌上找到解决方案

在ASP.NETCore中,是否可以编写一个自定义模型绑定器或类似的东西,使我能够在web API中获得一些继承支持

基本上我有一门课,比如:

public class Order {
   public Guid Id { get; set; }
   public PaymentContainer PaymentParameters { get; set; }
}
还有一个容器类,比如

public class PaymentContainer 
{
    public string Type { get; set; }

    public IPaymentParameters Value { get; set; }
}
以及一些实现
IPaymentParameters
接口的类和控制器方法,例如:

[HttpPost]
public IActionResult CreateOrder([FromBody]Order order)
{
}
我非常希望客户端能够发送json,例如:

{
  "id" : "1234-..-1234",
  "paymentParameters" : {
      "type": "SpecialParameters1",
      "value" : { /* instance of specialparameters1 here */ }
  }
}
然后让“value”属性在到达控制器方法后成为“SpecialParameters1”的实例

我认为写一个modelbinder是可能的,但我不知道该怎么做

注意:我知道可以更改Json.Net TypeNameHandling的方法,但我不想弄乱依赖Json序列化程序的所有其他东西,只要将其设置为Auto或all,就会为远程代码执行开辟一些途径

澄清:第一个答案后的小更新 目标是拥有多个参数实例,以便以下输入也“起作用”

当然我也会上课

public class SpecialParameters1 : IPaymentParameters{}
public class SpecialParameters2 : IPaymentParameters{}

是的,它ASP.NET Core在模型绑定方面相当出色,我将为您设置一个示例(刚刚对您的类进行了一点重构-不确定您需要做什么,但作为一个原则的演示,我认为它将非常适合)

在视图中,您可以设置如下内容:

<h2>orders with ajax</h2>
<dl>
    <dt>Order Id:</dt>
    <dd id="order-id">D3BCDEEE-AE26-4B20-9170-D1CA01B52CD4</dd>

    <dt>Payment container - Type</dt>
    <dd id="order-paymentcontainer-type">Card payment</dd>

    <dt>Payment Parameters - Name</dt>
    <dd id="order-paymentcontainer-paymentParameters-name">Card payment nr. 1</dd>

    <dt>Payment Parameters - Provider</dt>
    <dd id="order-paymentcontainer-paymentParameters-provider">Big Bank</dd>
</dl>
<a id="submit-button">Process order</a>


@section Scripts {
    <script src="~/js/paymentTest.js"></script>
}
然后写上你的paymentTest.cs

var order = {
        Id: "",
        PaymentContainer: {
            Type: "",
            PaymentParameters: {
                Name: "",
                Provider: ""
            }
        }
    };

order.Id = document.getElementById("order-id").innerHTML;
order.PaymentContainer.Type = document.getElementById("order-paymentcontainer-type").innerHTML;
order.PaymentContainer.PaymentParameters.Name = document.getElementById("order-paymentcontainer-paymentParameters-name").innerHTML;
order.PaymentContainer.PaymentParameters.Provider = document.getElementById("order-paymentcontainer-paymentParameters-provider").innerHTML;

$("#submit-button").click(function () {
    $.ajax({
        url: 'api/orders',
        type: 'POST',
        dataType: "json",
        contentType: 'application/json',
        data: JSON.stringify(order),
        success: function (data) {
            location.reload();
        }
    });
});
最后在控制器设置方法中进行绑定

[Route("api/orders")]
[HttpPost]
public async Task ProcessOrder([FromBody] Order order)
{
    var orders = new List<Order>();
    orders.Add(order);

    // and some other code ...
}
[路线(“api/订单”)]
[HttpPost]
公共异步任务ProcessOrder([FromBody]Order)
{
var orders=新列表();
订单。添加(订单);
//还有其他一些代码。。。
}

如果我错了,请纠正我-这里的主要问题是您无法从返回到控制器的视图绑定数据

您不能绑定,因为您的Order类(间接)包含接口,而MVC不能绑定接口。 这没关系,因为接口抽象行为而不是数据

此问题的潜在解决方法是在CreateOrder方法中使用OrderViewModel而不是Order类型。 i、 e:

然后OrderViewModel将使用PaymentContainerServiceModel而不是PaymentContainer, 它会有具体的价值
不是界面IPaymentParameters值,而是绑定。感谢您尝试给出答案,但这并不能真正解决我的问题-请参阅问题的澄清/更新。我不太确定您想做什么,所以我设置了一个允许一些测试的小代码案例。请参阅下面答案中的解决方法。对任何类型的描述都说不!!:这有什么帮助@Esben Bach?嗯,我试着写我自己的活页夹,但我似乎无法弄清楚我到底需要做什么才能得到我想要的结果。我会把这个答案和你的第二个答案结合起来:)也许用不同的标题把它们分开,答案1和答案2。只是想一想。是的,你的权利,将来会这样做的。:)
var order = {
        Id: "",
        PaymentContainer: {
            Type: "",
            PaymentParameters: {
                Name: "",
                Provider: ""
            }
        }
    };

order.Id = document.getElementById("order-id").innerHTML;
order.PaymentContainer.Type = document.getElementById("order-paymentcontainer-type").innerHTML;
order.PaymentContainer.PaymentParameters.Name = document.getElementById("order-paymentcontainer-paymentParameters-name").innerHTML;
order.PaymentContainer.PaymentParameters.Provider = document.getElementById("order-paymentcontainer-paymentParameters-provider").innerHTML;

$("#submit-button").click(function () {
    $.ajax({
        url: 'api/orders',
        type: 'POST',
        dataType: "json",
        contentType: 'application/json',
        data: JSON.stringify(order),
        success: function (data) {
            location.reload();
        }
    });
});
[Route("api/orders")]
[HttpPost]
public async Task ProcessOrder([FromBody] Order order)
{
    var orders = new List<Order>();
    orders.Add(order);

    // and some other code ...
}
public IActionResult CreateOrder([FromBody]OrderViewModel order)