How do I use MVC model binding to get data from SendGrid Inbound Parse Webhook in Asp.net MVC?

生来就可爱ヽ(ⅴ<●) 提交于 2020-04-10 06:33:07

问题


I am looking at implementing the SendMail Inbound Parse Webhook but have found that the examples they provide seem to fall a long way short of a perfect solution.

https://sendgrid.com/docs/Code_Examples/Webhook_Examples/csharp.html#-Parse-Webhook

[HttpPost]
public async Task<HttpResponseMessage> Post()
{
  var root = HttpContext.Current.Server.MapPath("~/App_Data");
  var provider = new MultipartFormDataStreamProvider(root);
  await Request.Content.ReadAsMultipartAsync(provider);

  var email = new Email
  {
      Dkim = provider.FormData.GetValues("dkim").FirstOrDefault(),
      To = provider.FormData.GetValues("to").FirstOrDefault(),
      Html = provider.FormData.GetValues("html").FirstOrDefault(),
      From = provider.FormData.GetValues("from").FirstOrDefault(),
      Text = provider.FormData.GetValues("text").FirstOrDefault(),
      SenderIp = provider.FormData.GetValues("sender_ip").FirstOrDefault(),
      Envelope = provider.FormData.GetValues("envelope").FirstOrDefault(),
      Attachments = int.Parse(provider.FormData.GetValues("attachments").FirstOrDefault()),
      Subject = provider.FormData.GetValues("subject").FirstOrDefault(),
      Charsets = provider.FormData.GetValues("charsets").FirstOrDefault(),
      Spf = provider.FormData.GetValues("spf").FirstOrDefault()
  };

  // The email is now stored in the email variable

  return new HttpResponseMessage(HttpStatusCode.OK);
}

This doesn't use model binding in any way which seems wrong to me. Also their code does not extract the attachments from the form data.

All advice, examples and help much appreciated.


回答1:


This is my current best solution for extracting the email data from the SendGrid Inbound Parse Webhook in .net.

Notice that it uses a normal MVC controller and not an WebApi Controller as the files do not seem to be attached to the Request in a WebApi controller.

Models:

public class InboundEmailInputModel
{
    public string Headers { get; set; }
    public string Text { get; set; }
    public string Html { get; set; }
    public string From { get; set; }
    public string To { get; set; }
    public List<string> Cc { get; set; }
    public string Subject { get; set; }
    public string Dkim { get; set; }
    public string Spf { get; set; }
    public InboundEmailEnvelopeInputModel Envelope { get; set; }
    public InboundEmailCharsetsInputModel Charsets { get; set; }
    public float SpamScore { get; set; }
    public string SpamReport { get; set; }
    public int Attachments { get; set; }
    public dynamic AttachmentInfo { get; set; }
    public HttpFileCollectionBase AttachmentFiles { get; set; }
    public string SenderIp { get; set; }
}


public class InboundEmailEnvelopeInputModel
{
    public string From { get; set; }
    public List<string> To { get; set; }
}


public class InboundEmailCharsetsInputModel
{
    public string From { get; set; }
    public string To { get; set; }
    public string Cc { get; set; }
    public string Html { get; set; }
    public string Subject { get; set; }
    public string Text { get; set; }
}

Controller

    [System.Web.Mvc.AllowAnonymous]
    [System.Web.Mvc.HttpPost]
    public async Task<HttpResponseMessage> Inbound()
    {
        var inboundEmail = await InboundEmailExtractor.ExtractInboundEmail(Request);

        return new HttpResponseMessage(HttpStatusCode.OK);
    }

Static Method

public static class InboundEmailExtractor
{
    public async static Task<InboundEmailInputModel> ExtractInboundEmail(HttpRequestBase request)
    {
        var serialiser = new JavaScriptSerializer();

        var inboundEmail = new InboundEmailInputModel();

        inboundEmail.Headers = request.Unvalidated.Form["headers"];
        inboundEmail.Text = request.Unvalidated.Form["text"];
        inboundEmail.Html = request.Unvalidated.Form["html"];
        inboundEmail.From = request.Unvalidated.Form["from"];
        inboundEmail.To = request.Unvalidated.Form["to"];
        inboundEmail.Cc = request.Unvalidated.Form["to"].Split(',').ToList();
        inboundEmail.Subject = request.Unvalidated.Form["subject"];
        inboundEmail.Dkim = request.Unvalidated.Form["dkim"];
        inboundEmail.Spf = request.Unvalidated.Form["spf"];

        var envelopeRaw = request.Unvalidated.Form["envelope"];
        if (envelopeRaw != null)
        {
            inboundEmail.Envelope = serialiser.Deserialize<InboundEmailEnvelopeInputModel>(envelopeRaw);
        }

        var charsetsRaw = request.Unvalidated.Form["charsets"];
        if (charsetsRaw != null)
        {
            inboundEmail.Charsets =
                new JavaScriptSerializer().Deserialize<InboundEmailCharsetsInputModel>(charsetsRaw);
        }

        var spamScoreRaw = request.Unvalidated.Form["spam_score"];
        if (spamScoreRaw != null)
        {
            inboundEmail.SpamScore = float.Parse(spamScoreRaw, CultureInfo.InvariantCulture.NumberFormat);
        }

        inboundEmail.SpamReport = request.Unvalidated.Form["spam_report"];

        var attachmentsRaw = request.Unvalidated.Form["attachments"];
        if (attachmentsRaw != null)
        {
            inboundEmail.Attachments = Convert.ToInt32(attachmentsRaw);
        }

        var attachmentInfoRaw = request.Unvalidated.Form["attachment-info"];
        if (attachmentInfoRaw != null)
        {
            inboundEmail.AttachmentInfo = System.Web.Helpers.Json.Decode(attachmentInfoRaw);
        }

        inboundEmail.SenderIp = request.Unvalidated.Form["sender_ip"];

        inboundEmail.AttachmentFiles = request.Files;

        return inboundEmail;
    }
}

Comments and ways of improving this much appreciated.



来源:https://stackoverflow.com/questions/28460357/how-do-i-use-mvc-model-binding-to-get-data-from-sendgrid-inbound-parse-webhook-i

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!