【发布时间】:2016-04-06 07:50:24
【问题描述】:
我有一个 WebAPI 控制器,它接受多部分表单数据格式的帖子。它这样做是因为我在同一个帖子中同时获取二进制文件和表单数据。
我尝试根据这个问题调整解决方案:How do I automap namevaluecollection to a strongly typed class?
这是修改后的代码:
private Event nvcToCoreEvent(NameValueCollection nvc) {
Event e = new Event();
foreach (string kvp in nvc.AllKeys) {
PropertyInfo pi = e.GetType().GetProperty(kvp, BindingFlags.Public | BindingFlags.Instance);
if (pi != null) {
pi.SetValue(e, nvc[kvp], null);
}
}
return e;
}
问题是来自nvc.AllKeys 的键都看起来像这样:"coreEvent[EventId]",或者这样:"coreEvent[AuthorUser][UserId]"
pi 始终为 null,并且没有任何内容被映射,因为 GetProperty 期望通过 "EventId",而不是 "coreEvent[EventId]"。如果只有几个属性,它不会那么糟糕,但是我的Event 类非常大,并且包含包含它们自己的子对象的子对象等。它还包含许多对象列表,它们也可以有它们的自己的子对象。
我是否可以编写一个键字符串解析器和映射引擎来将值映射到正确的子对象或集合?
编辑 这是请求的类和示例数据:
事件类
public class Event {
public Event() {
Documents = new List<Document>();
SignOffs = new List<SignOff>();
CrossReferences = new List<CrossReference>();
Notes = new List<Note>();
HistoryLogs = new List<HistoryLog>();
}
public int EventId { get; set; }
public string EventTitle { get; set; }
public User AuthorUser { get; set; }
public User RMUser { get; set; }
public User PublisherUser { get; set; }
public User MoPUser { get; set; }
public EventStatus EventStatus { get; set; }
public WorkPath WorkPath { get; set; }
public Stage Stage { get; set; }
public string EventSummary { get; set; }
public User EventSummaryLastModifiedByUser { get; set; }
public DateTime? EventSummaryLastModifiedOnDate { get; set; }
public Priority Priority { get; set; }
public DateTime? DesiredPublicationDate { get; set; }
public DateTime? DesiredEffectiveDate { get; set; }
public string EffectiveDateReason { get; set; }
public DateTime? AssessmentTargetDate { get; set; }
public DateTime? AssessmentActualDate { get; set; }
public DateTime? SMTargetDate { get; set; }
public DateTime? SMActualDate { get; set; }
public DateTime? FRSOTargetDate { get; set; }
public DateTime? FRSOActualDate { get; set; }
public DateTime? BLRTargetDate { get; set; }
public DateTime? BLRActualDate { get; set; }
public DateTime? SSOTargetDate { get; set; }
public DateTime? SSOActualDate { get; set; }
public DateTime? BLSOTargetDate { get; set; }
public DateTime? BLSOActualDate { get; set; }
public DateTime? FSOTargetDate { get; set; }
public DateTime? FSOActualDate { get; set; }
public DateTime? PublicationTargetDate { get; set; }
public DateTime? PublicationActualDate { get; set; }
public DateTime? EffectiveTargetDate { get; set; }
public DateTime? EffectiveActualDate { get; set; }
public User EffectiveDateReasonLastModifiedByUser { get; set; }
public DateTime? EffectiveDateReasonLastModifiedOnDate { get; set; }
public DateTime? CancellationDate { get; set; }
public string CancellationReason { get; set; }
public DateTime? OnHoldEnteredDate { get; set; }
public DateTime? OnHoldReminderDate { get; set; }
public bool TranslationRequired { get; set; }
public string NewsItemNumber { get; set; }
public string PublicationIdNumber { get; set; }
public IList<Document> Documents { get; set; }
public IList<SignOff> SignOffs { get; set; }
public IList<CrossReference> CrossReferences { get; set; }
public IList<Note> Notes { get; set; }
public IList<HistoryLog> HistoryLogs { get; set; }
public SaveType SaveType { get; set; }
public Stage DestinationStage { get; set; }
}
这是NameValueCollection 中的一些键示例。
包含集合索引的键:
coreEvent[Documents][0][UploadedByUser][Team][Department][Division][DivisionName]
列表中的列表:
coreEvent[SignOffs][1][Comments][0][LastModifiedByUser][Team][Department][Division][DivisionName]
最后一个应该读作coreEvent是一个包含SignOff对象列表的对象,每个对象都包含Comment对象列表,每个对象都包含User对象,其中包含Team对象其中包含一个 Department 对象,该对象包含一个 Division 对象,该对象包含一个名为 DivisionName 的字符串属性。
【问题讨论】:
-
您可以发布示例数据和您的 Event 类吗?
-
@JleruOHeP 添加了示例数据和事件类
-
听起来您想要做的是创建自己的 IModelBinder 来替换默认的 MVC 。我找到了一个 CodeProject article,它描述了你自己做这件事(一旦你想出了正确的实现)。
标签: c# .net asp.net-web-api