asp-for does not work when using 'name=' property to pass data to controller

DMur 46 Reputation points
2021-08-15T16:39:07.583+00:00

Hi, I'm having trouble getting my asp validation to work when I have a name attribute to pass data to my controller.

When I use the below code, my client side validation works fine, but I am not sending any data back to my controller (Because there is no name="" parameter):

            <div class="form-group">
                <label class="font-heading" asp-for="Email" id="ContactUsEmailHeading">Email</label>
                <input asp-for="Email" class="form-control" id="ContactUsEmailField" />
                <span asp-validation-for="Email" class="text-danger"></span>
            </div>

When I add the name attribute to send data to the controller, the client side validation functions, but the validation messages do not display.

            <div class="form-group">
                <label class="font-heading" asp-for="Email" id="ContactUsEmailHeading">Email</label>
                <input asp-for="Email" name="ContactUsEmailField" class="form-control" id="ContactUsEmailField" />
                <span asp-validation-for="Email" class="text-danger"></span>
            </div>

I thought it may be that the validation is displaying but the page is refreshing before I can see it. Upon checking, the method is not executing. So the validation is still working, just the messages are not showing.

My controller:

[HttpPost]
public async Task<IActionResult> SendMail(string ContactUsNameField, string ContactUsEmailField, string ContactUsSubjectField, string ContactUsMessageField, bool ContactUsTandCCheckbox)
{
    DateTime FeedbackDateTime = DateTime.UtcNow;

    if (ModelState.IsValid)
    {
        try
        {
            await SaveContactFormEntry.saveUserEntryAsync(FeedbackDateTime, ContactUsNameField, ContactUsEmailField, ContactUsSubjectField, ContactUsMessageField, ContactUsTandCCheckbox);
        }
        catch (Exception ex)
        {
            return RedirectToAction("Help");
        }
    }

    return RedirectToAction("Help");
}

Could someone please help me to get my validation working while also passing data to the controller?

Developer technologies ASP.NET ASP.NET Core
Developer technologies C#
{count} votes

Accepted answer
  1. AgaveJoe 30,126 Reputation points
    2021-08-15T18:34:16.27+00:00

    If the asp-for tag sets the name automatically, why does it not work if I remove the name tag so as not to set it manually?

    Because you are not following standard MVC Core patterns and practices. I strongly recommend going through the tutorial in my first post which covers many basic concepts. I also recommend the data access tutorial. There is a lot of great information in these tutorials.

    The following code sample is a minimalistic example using a Model, View, and Controller with standard model validation.

    namespace MvcDemo.Controllers  
    {  
        public class FromViewModel  
        {  
            [Required]  
            public string Name { get; set; }  
        }  
      
        public class FormController : Controller  
        {  
            private readonly ILogger<FormController> _logger;  
            public FormController(ILogger<FormController> logger)  
            {  
                _logger = logger;  
            }  
      
            [HttpGet]  
            public IActionResult Index()  
            {  
                return View();  
            }  
      
            [HttpPost]  
            public IActionResult Index(FromViewModel model)  
            {  
                _logger.LogInformation(model.Name);  
                return View(model);  
            }  
      
      
        }  
    }  
    

    Markup

    @model MvcDemo.Controllers.FromViewModel  
      
    @{  
        ViewData["Title"] = "Index";  
    }  
      
    <h1>Index</h1>  
      
    <h4>FromViewModel</h4>  
    <hr />  
    <div class="row">  
        <div class="col-md-4">  
            <form asp-action="Index">  
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>  
                <div class="form-group">  
                    <label asp-for="Name" class="control-label"></label>  
                    <input asp-for="Name" class="form-control" />  
                    <span asp-validation-for="Name" class="text-danger"></span>  
                </div>  
                <div class="form-group">  
                    <input type="submit" value="Create" class="btn btn-primary" />  
                </div>  
            </form>  
        </div>  
    </div>  
      
    <div>  
        <a asp-action="Index">Back to List</a>  
    </div>  
    
    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Rena Ni - MSFT 2,066 Reputation points
    2021-08-16T02:07:55.097+00:00

    Hi @DMur ,

    1. asp-for="Email" will generate to html like: id="Email" name="Email" by default. If you specify the name and id, they will override the default id and name.
    2. Model binding system will bind the value by name in html.

    I think an easy way is to change your backend parameter name to Email:

     public async Task<IActionResult> SendMail(string ContactUsNameField, string Email, string ContactUsSubjectField, string ContactUsMessageField, bool ContactUsTandCCheckbox)  
    

    The razor view keep like below:

    <input asp-for="Email"  class="form-control" id="ContactUsEmailField" />  
    

    If the answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best Regards,

    Rena

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.