I’m working on a C# MVC project and need to build an endpoint that processes incoming emails sent through Mailgun’s forwarding service. I found their documentation but the example is written in Python which I’m not comfortable with.
Here’s their Python sample:
def handle_email_webhook(request):
if request.method == 'POST':
from_email = request.POST.get('sender')
to_email = request.POST.get('recipient')
email_subject = request.POST.get('subject', '')
plain_content = request.POST.get('body-plain', '')
clean_text = request.POST.get('stripped-text', '')
# handle file uploads
for file_key in request.FILES:
uploaded_file = request.FILES[file_key]
# process the attachment
# Return 200 status or Mailgun will retry in 5 minutes
return HttpResponse('OK')
Can someone show me how to create a similar controller action in C# that extracts the email data from the POST request? Any working example would be really helpful.
I’ve been handling Mailgun webhooks in ASP.NET MVC for two years - here’s what actually works. Set up a controller action that takes form data since Mailgun sends everything as form-encoded POST. Use Request.Form to grab the fields directly instead of model binding. The field names have hyphens and they don’t mesh well with C# properties.
[HttpPost]
public ActionResult ProcessInboundEmail()
{
var sender = Request.Form["sender"];
var recipient = Request.Form["recipient"];
var subject = Request.Form["subject"] ?? string.Empty;
var bodyPlain = Request.Form["body-plain"] ?? string.Empty;
var strippedText = Request.Form["stripped-text"] ?? string.Empty;
// Handle attachments
foreach (string fileKey in Request.Files)
{
var file = Request.Files[fileKey];
if (file != null && file.ContentLength > 0)
{
// Process your attachment here
}
}
return new HttpStatusCodeResult(200, "OK");
}
Add [ValidateInput(false)] if you’re processing HTML content, or ASP.NET will throw validation errors for potentially dangerous input.
The signature verification totally caught me off guard. Mailgun sends security tokens that you need to validate - otherwise spam bots will hammer your endpoint. I’d create a model class to keep things clean, even though the form fields have hyphens. Just map them manually.
public class MailgunInboundModel
{
public string Sender { get; set; }
public string Recipient { get; set; }
public string Subject { get; set; }
public string BodyPlain { get; set; }
public string Timestamp { get; set; }
public string Token { get; set; }
public string Signature { get; set; }
}
[HttpPost]
public ActionResult HandleInbound()
{
var model = new MailgunInboundModel
{
Sender = Request.Form["sender"],
Recipient = Request.Form["recipient"],
Subject = Request.Form["subject"],
BodyPlain = Request.Form["body-plain"],
Timestamp = Request.Form["timestamp"],
Token = Request.Form["token"],
Signature = Request.Form["signature"]
};
// Verify webhook authenticity here
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
Also make sure to whitelist your endpoint URL in the Mailgun control panel under Routes configuration.
heads up - disable CSRF protection for that endpoint or you’ll get 500 errors when mailgun posts. Add [ValidateAntiForgeryToken(false)] or exclude the route from antiforgery checks in your config. learned this the hard way when my webhook kept failing