c# - 自定义集合的 NotSupportedException
问题描述
问题:
我有一个接受 IEmail 输入的 API 端点:
[HttpPost]
[Route("SendAsync")]
public async Task SendAsync(IEmail email)
{
await this._emailService.SendAsync(email);
}
问题似乎出在此输入的 Attachments 属性的模型绑定上。模型绑定器似乎无法反序列化到我的实现。这很奇怪,因为 IEmail 似乎没问题...
例外:
System.NotSupportedException: The collection type 'IAttachmentCollection' on 'IEmail.Attachments' is not supported.
设置:
请参阅下文了解我的 IEmail 合同和实施:
public interface IEmail
{
string To { get; set; }
string Subject { get; set; }
string Body { get; set; }
IAttachmentCollection Attachments { get; set; }
bool HasAttachments { get; }
}
public class EmailMessage : IEmail
{
public EmailMessage()
{
this.Attachments = new AttachmentCollection();
}
public string To { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public IAttachmentCollection Attachments { get; set; }
public bool HasAttachments => this.Attachments != null && this.Attachments.Any(x => x.Content.Length > 0);
}
我创建了一个自定义集合,以便可以将自定义验证添加到集合的 Add() 例程中:
public interface IAttachmentCollection : ICollection<IAttachment>
{
}
public class AttachmentCollection : IAttachmentCollection
{
private ICollection<IAttachment> _attachments;
public AttachmentCollection()
{
this._attachments = new HashSet<IAttachment>();
}
public void Add(IAttachment item)
{
// Do some custom validation on the item we are trying to add
this._attachments.Add(item);
}
// Other implemented methods for ICollection<T>...
}
解决方案
对于复杂类型,模型默认是具有默认构造函数的具体非抽象类,以便能够绑定操作。它也无法确定接口属性使用什么类Attachments
。
ASP.NET Core 中的参考模型绑定
创建一个反映所需对象图的模型
public class EmailModel {
public EmailModel() {
this.Attachments = new List<AttachmentModel>();
}
public string To { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public List<AttachmentModel> Attachments { get; set; }
public bool HasAttachments => this.Attachments != null && this.Attachments.Any(x => x.Content.Length > 0);
}
public class AttachmentModel {
//...members
}
明确地将其用于操作
[HttpPost]
[Route("SendAsync")]
public async Task<IActionResult> SendAsync([FromBody]EmailModel model) {
if(ModelState.IsValid) {
IEmain email = new EmailMessage();
//...code here to map model to the desired type
await this._emailService.SendAsync(email);
return Ok();
}
return BadRequest(ModelState);
}
确保将发布的数据映射到所需的类型
推荐阅读
- java - javax.mail - 强制 IMAP 使用 TLS1.2+ - “收到致命警报:protocol_version”
- xquery - MarkLogic:持久化并重用 Xquery 结果
- ssis - SSIS 目录更改恢复到以前的版本 - 参数和连接管理器
- css - CSS 动画挂起/绊倒
- download - 使用 Ansible 从 Windows 共享下载文件
- excel - IF 上的 Excel 错误,`=IF(TRUE, 1, 2)` 是无效的语法?
- c# - 如何在我的控制器中获得新的 ApiAuthorizationDbContext
- spring-boot - 测试 bootstrap.properties 中的 Spring Boot 2.2.4 未加载包含的 application.properties 配置文件
- c# - 如何遍历字典并将项目添加到其值
- google-chrome-extension - background.js 没有收到 chrome.runtime 消息