У меня есть контроллер WebAPI, который принимает сообщения в формате данных с несколькими формами. Он делает это, когда я получаю двоичные файлы и данные формы в одной и той же записи.Преобразование formdata NameValueCollection в объект
Я попытался адаптировать решение от этого вопроса: 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
очень большой и содержит под-объекты, которые содержат свои собственные под-объекты и т. Д. Он также содержит много списков объектов, которые также могут иметь свой собственный суб-объект -объекты.
Есть ли у меня альтернатива написанию синтаксического анализатора строк и механизма отображения для сопоставления значений правильному под-объекту или коллекции?
EDIT Вот запрошенный класс и выборка данных:
Класс событий
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
, который содержит строку p roperty называется DivisionName
.
Можете ли вы разместить данные примера и свой класс событий? – JleruOHeP
@JleruOHeP добавил примеры данных и класс событий – Legion
Похоже, что вы хотите создать собственный IModelBinder для замены MVC по умолчанию. Я нашел CodeProject [article] (http://www.codeproject.com/Articles/605595/ASP-NET-MVC-Custom-Model-Binder), который описывает это самостоятельно (как только вы придумаете правильную реализацию). – mason