如何在我的MVC应用程序中处理Postmark的大型JSON输入?

Tim*_*man 5 model-view-controller asp.net-mvc model-binding custom-model-binder

这与这个问题有关,但在这种情况下,它不是我要返回的东西,而是模型绑定.我正在使用Postmark来处理传入的电子邮件,这些电子邮件会发布到具有JSON有效负载的页面.

我有一个如下所示的模型和一个接受此JSON有效负载(使用application/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; }

}
Run Code Online (Sandbox Code Playgroud)

这适用于小附件,但对于超出默认值maxJsonLength属性的任何内容都会导致反序列化错误.("使用JSON JavaScriptSerializer进行序列化或反序列化时出错.字符串的长度超过了maxJsonLength属性上设置的值.")因为我想接受图像附件,这意味着大多数图像都会失败.

我已经尝试更新web.config,但是根据其他线程,这对MVC控制器没有帮助.我想我可能会做自定义IModelBinder中提到的内容,但我正在努力如何拦截反序列化.(换句话说,它仍然失败,因为已经发生了反序列化).

有什么建议?我确定这只是一件让我失踪的蠢事....

Dar*_*rov 3

您可以编写一个使用Json.NET的自定义 JsonValueProviderFactory

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

并在你的Application_Start

ValueProviderFactories.Factories.Remove(ValueProviderFactories.Factories.OfType<JsonValueProviderFactory>().FirstOrDefault());
ValueProviderFactories.Factories.Add(new JsonDotNetValueProviderFactory());
Run Code Online (Sandbox Code Playgroud)