5

Это связано с этим question, но в данном случае это не то, что я возвращаю, а скорее привязку модели. Я использую Postmark для обработки входящих писем, которые отправляются на страницу с JSON payload.Как я могу обрабатывать большой вход JSON из Postmark в моем приложении MVC?

У меня есть модель, как показано ниже, и действие, которое принимает эту полезную нагрузку JSON (отправляется с помощью приложения/json) и обрабатывает ее.

public class EmailModel 
{ 
    public IDictionary<string, string> Headers { get; set; } 
    public string From { get; set; } 
    public string Cc { get; set; } 
    public string HtmlBody { get; set; } 
    public string TextBody { get; set; } 
    public string ReplyTo { get; set; } 
    public string Tag { get; set; } 
    public string To { get; set; } 
    public string MessageID { get; set; } 
    public string MailboxHash { get; set; } 
    public string Subject { get; set; } 
    public List<Attachment> Attachments { get; set; } 
} 

public class Attachment 
{ 
    public string Content { get; set; } 
    public int ContentLength { get; set; } 
    public string ContentType { get; set; } 
    public string Name { get; set; } 

} 

Это прекрасно работает для небольших вложений, но и для всего, что превышает maxJsonLength свойства по умолчанию вызывает ошибку в десериализации. («Ошибка при сериализации или десериализации с помощью JSON JavaScriptSerializer. Длина строки превышает значение, установленное в свойстве maxJsonLength».) Поскольку я хочу принимать вложения изображений, это означает, что большинство изображений не работают.

Я пробовал обновлять файл web.config, но в соответствии с этими другими потоками это не помогает для контроллеров MVC. Я полагаю, что, возможно, я смогу сделать то, что было упомянуто в пользовательском IModelBinder, но я изо всех сил пытаюсь перехватить десериализацию. (Другими словами, он все еще терпит неудачу, поскольку десериализация уже произошла).

Любые предложения? Я уверен, что это просто что-то глупо, что я пропускаю ....

ответ

3

Вы можете написать custom JsonValueProviderFactory, который использует Json.NET:

public sealed class JsonDotNetValueProviderFactory : ValueProviderFactory 
{ 
    public override IValueProvider GetValueProvider(ControllerContext controllerContext) 
    { 
     if (controllerContext == null) 
      throw new ArgumentNullException("controllerContext"); 

     if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase)) 
      return null; 

     var reader = new StreamReader(controllerContext.HttpContext.Request.InputStream); 
     var bodyText = reader.ReadToEnd(); 

     return String.IsNullOrEmpty(bodyText) ? null : new DictionaryValueProvider<object>(JsonConvert.DeserializeObject<ExpandoObject>(bodyText, new ExpandoObjectConverter()) , CultureInfo.CurrentCulture); 
    } 
} 

и в вашем Application_Start:

ValueProviderFactories.Factories.Remove(ValueProviderFactories.Factories.OfType<JsonValueProviderFactory>().FirstOrDefault()); 
ValueProviderFactories.Factories.Add(new JsonDotNetValueProviderFactory()); 
+0

Спасибо Дарина - выглядит как хороший подход. Я собираюсь сделать этот снимок завтра. –

+0

@Darin Есть ли способ добавить это только к определенному контроллеру вместо всего приложения? –

+0

Привет, Дарин, не могли бы вы взглянуть на [мой вопрос] (http://stackoverflow.com/q/32970848/7850), чтобы понять, почему это не работает для меня? Благодаря! –