/// <summary> /// /// </summary> /// <typeparam name="TResult"></typeparam> /// <returns></returns> /// <exception cref="JsonModelReaderException"></exception> private async Task <TResult> ReadAsMultipart <TResult>() where TResult : IJsonModel, IAttachmentByHash, new() { var result = new TResult(); string boundary = GetBoundary(); var multipartReader = new MultipartReader(boundary, Body); int sectionIndex = 0; while (true) { MultipartSection section = await multipartReader.ReadNextSectionAsync(); if (section == null) { break; } var sectionContentType = ParseContentType(section.ContentType); if (sectionIndex == 0) { if (!IsApplicationJson(sectionContentType.MediaType)) { throw new JsonModelReaderException($"First part must have a Content-Type header value of \"{MediaTypes.Application.Json}\"."); } try { result = (TResult)ReadAs <TResult>(await ReadAsJson(section.Body)); } catch (MultipartSectionException ex) { throw new JsonModelReaderException("", ex); } } else { MultipartAttachmentSection attachmentSection; try { attachmentSection = new MultipartAttachmentSection(section); } catch (MultipartSectionException ex) { throw new JsonModelReaderException($"Invalid Multipart attachment section.", ex); } string hash = attachmentSection.XExperienceApiHash; var attachment = result.GetAttachmentByHash(hash); if (attachment != null) { attachment.SetPayload(await attachmentSection.ReadAsByteArrayAsync()); } else { throw new JsonModelReaderException($"Header '{Data.Http.ExperienceApiHeaders.XExperienceApiHash}: {hash}' does not match any attachments."); } } sectionIndex++; } return(result); }