c# - 用于继承/类型区分的自定义模型绑定器
问题描述
抱歉,如果这个问题已经被问了一百万次,但我似乎无法在 Google 或 SO 上找到解决方案。
在 ASP.NET Core 中,是否可以编写自定义模型绑定器或类似的东西,这将允许我在 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”的一个实例,一旦它到达控制器方法。
我认为可以编写一个模型绑定器,但我不能完全理解它是如何完成的。
注意:我知道可以更改 Json.Net TypeNameHandling 的方法,但我宁愿不搞乱所有其他依赖 json 序列化程序的东西,而只需将其设置为 Auto 或 All 将开辟一些途径远程代码执行。
澄清:第一个答案后的小更新目标是有多个参数实例,这样以下输入也“有效”
{
"id" : "1234-..-1234",
"paymentParameters" : {
"type": "SpecialParameters2",
"value" : { /* instance of specialparameters2 here */ }
}
}
当然我会上课
public class SpecialParameters1 : IPaymentParameters{}
public class SpecialParameters2 : IPaymentParameters{}
解决方案
Yes, it ASP.NET Core is quite good at model binding, I will setup example for you (just had refactored a little your classes - not sure in details what you have to do, but as a demonstration of a principle I think it will suit well)
In View you setup something like this:
<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>
}
Then you setup classes:
public class Order
{
public Guid Id { get; set; }
public PaymentContainer PaymentContainer { get; set; }
}
public class PaymentContainer
{
public string Type { get; set; }
public PaymentParameters PaymentParameters { get; set; }
}
public class PaymentParameters
{
public string Name { get; set; }
public string Provider { get; set; }
}
Then write in your 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();
}
});
});
And finally in controller setup method for binding
[Route("api/orders")]
[HttpPost]
public async Task ProcessOrder([FromBody] Order order)
{
var orders = new List<Order>();
orders.Add(order);
// and some other code ...
}
推荐阅读
- java - 我无法在我的 Java 图像查看器中看到图像
- git - Git - 已经在命令行中的分支上,但分支在 Atom 的 git 插件中不可用
- php - 从 DB 和 PHP 刷新模态 AJAX 内容动态
- java - 不能在 OnClickListener 上抛出 IOException
- tensorflow - TensorFlow XOR 实现,无法达到 100% 的准确率
- reactjs - 如何在样式化组件中定义 className
- firebase - 将 firebase 导入到 react-native
- java - Java 从 URL NullPointerException 解析 JSON
- java - 基于其他两个对象的子类创建对象
- php - 更新用于在 PHP 中解析 XML 的 URL