Converting formdata NameValueCollection to object
<p>I have a WebAPI controller that accepts posts in multipart form data format. It does this as I'm getting both binary files and form data in the same post.</p>

<p>I tried adapting the solution from this question: <a href="https://stackoverflow.com/questions/2338220/how-do-i-automap-namevaluecollection-to-a-strongly-typed-class">How do I automap namevaluecollection to a strongly typed class?</a></p>

<p>Here's the adapted code:</p>

<pre><code>    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;
    }
</code></pre>

<p>The problem is the keys coming from <code>nvc.AllKeys</code> all look like this: <code>"coreEvent[EventId]"</code>, or this: <code>"coreEvent[AuthorUser][UserId]"</code></p>

<p><code>pi</code> is always null and nothing gets mapped since <code>GetProperty</code> expects to be passed <code>"EventId"</code>, not <code>"coreEvent[EventId]"</code>. If there were just a few properties it wouldn't be so bad but my <code>Event</code> class is very big and contains sub-objects which contain their own sub-objects, etc. It also contains many lists of objects which can also have their own sub-objects.</p>

<p>Is there any alternative to me writing a key string parser and mapping engine to map the values to the correct sub-object or collection?</p>

<p>EDIT
Here's the requested class and sample data:</p>

<p>Event Class</p>

<pre><code>public class Event {
    public Event() {
        Documents = new List&lt;Document&gt;();
        SignOffs = new List&lt;SignOff&gt;();
        CrossReferences = new List&lt;CrossReference&gt;();
        Notes = new List&lt;Note&gt;();
        HistoryLogs = new List&lt;HistoryLog&gt;();
    }

    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&lt;Document&gt; Documents { get; set; }
    public IList&lt;SignOff&gt; SignOffs { get; set; }
    public IList&lt;CrossReference&gt; CrossReferences { get; set; }
    public IList&lt;Note&gt; Notes { get; set; }
    public IList&lt;HistoryLog&gt; HistoryLogs { get; set; }
    public SaveType SaveType { get; set; }
    public Stage DestinationStage { get; set; }
}
</code></pre>

<p>Here's some samples of the keys in the <code>NameValueCollection</code>.</p>

<p>A key including an index into a collection:
<code>coreEvent[Documents][0][UploadedByUser][Team][Department][Division][DivisionName]</code></p>

<p>List within a list:
<code>coreEvent[SignOffs][1][Comments][0][LastModifiedByUser][Team][Department][Division][DivisionName]</code></p>

<p>This last one should read as <code>coreEvent</code> is an object containing a list of <code>SignOff</code> objects each of which contains a list of <code>Comment</code> objects each of which contains a <code>User</code> object which contains a <code>Team</code> object which contains a <code>Department</code> object which contains a <code>Division</code> object which contains a string property called <code>DivisionName</code>.</p>