Action Arguments in ASP.NET Core

Action Arguments in ASP.NET Core

Action Arguments in ASP.NET Core: What's Best?

When handling form posts in ASP.NET Core, developers often ask:

Should I use IFormCollection, individual parameters, or a ViewModel?

The answer depends on the form size, your need for validation, and how much control you want over the incoming data. Here’s how I approach it after decades of building robust web apps and platforms.


✅ Option 1: IFormCollection

Use this when you want full access to the raw form data, especially for dynamic or variable-length forms.

[HttpPost]
public async Task<IActionResult> Contact(IFormCollection form)
{
    var email = form["Email"];
    var message = form["message"];
    var captcha = form["cfTurnstileResponse"];
}

🔹 Advantages:

  • You get all the keys and values, even if they don’t match any class or parameter.
  • Great for logging or analytics.
  • Perfect for optional fields or wizard-style forms.

❌ Downsides:

  • You’re on your own for validation.
  • Everything is a string — you’ll do more parsing and error checking.

✅ Option 2: Individual Parameters

For simple, predictable forms, direct parameters keep it clean:

[HttpPost]
public async Task<IActionResult> Contact(string email, string message, string cfTurnstileResponse)

🔹 Advantages:

  • Clean, readable method signatures.
  • Leverages automatic model binding.
  • Easy to validate with data annotations.

❌ Downsides:

  • Field names must match exactly — fragile if front-end changes.
  • Not scalable for big or dynamic forms.

✅ Option 3: ViewModel — The Sweet Spot

A ViewModel combines clarity, validation, and flexibility. It’s what I use in nearly every serious project.

public class ContactFormModel {
    public string Email { get; set; }
    public string Message { get; set; }
    public string CfTurnstileResponse { get; set; }
}

[HttpPost]
public async Task<IActionResult> Contact(ContactFormModel model)

🔹 Benefits:

  • Supports validation with [Required], [EmailAddress], etc.
  • Keeps controller logic tidy and testable.
  • Encourages separation of concerns.

If you're building on my DevStack platform, this pattern is already built-in with global model validation, anti-spam hooks, and localization.


💡 My Recommendation

Use CaseBest Practice
Simple known fieldsIndividual parameters or ViewModel
Many optional/dynamic fieldsIFormCollection
Want validation + clarityViewModel

Why This Matters

Clean input handling is about more than preference — it affects security, maintainability, and speed of development.

If you’re working on forms now or migrating older code, I’ve already done this groundwork. My consulting services give you access to:

Need help implementing or modernizing your form handling? Let’s talk.

Also see: Pricing | My CV