Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pass selected dropdown list value from View to Controller

Tags:

c#

asp.net-mvc

I want to pass a parameter (string) to my Controller from my View. The value should be that which is selected from a dropdown list in the view. The method is called after a button-click, but in the Controller, the parameter is always null.

In the View:

    @using (Html.BeginForm("Send", "Overview", FormMethod.Get))
    {
        <p>Email: @Html.DropDownList("Emails", Model.GetEmails())
        <input type="submit" value="Send" />
        </p>

    }

In the Controller:

    public ActionResult Send(string email)
    {
        // email is always null!
        return null;
    }

In the Overview model:

    private List<SelectListItem> emails;
    ...
    public Overview()
    {
        emails = new List<SelectListItem>();
        emails.Add(new SelectListItem() { Text = "[email protected]", Value = "[email protected]", Selected = true });
        emails.Add(new SelectListItem() { Text = "[email protected]", Value = "[email protected]", Selected = false });
        emails.Add(new SelectListItem() { Text = "[email protected]", Value = "[email protected]", Selected = false });
    }
    ...
    public List<SelectListItem> GetEmails()
    {
        return emails;
    }

Could you please help me get this work? What am I missing? (Btw, never mind the Controller returning null for now please :)).

like image 474
user3147607 Avatar asked Dec 16 '22 02:12

user3147607


1 Answers

From your terminology I'm guessing you're confused about what's going on. You never send anything from the view to the controller. Instead the view is something that assembles Html to send to the web browser. So what's actually happening is this:

  • Your browser requests /MyApp/Overview from your server (IIS)
  • IIS picks it up and sends that to Asp.Net
  • Asp.Net Mvc sees the request and through routing figures out that you want to call the Overview method on the MyAppController class
  • The method runs and produces a Model
  • Asp.Net Mvc passes the model to the view engine which runs your view to produce html
  • The html is returned to IIS which sends it to your browser
  • Your browser displays the html as a select control.
  • The user makes a selection and clicks "submit" on the form
  • The browser encodes their submission and sends it to the url in the form's action attribute (eg <form method=POST action="/MyApp/Send>)
  • IIS picks that up and sends that to Asp.Net
  • Asp.Net Mvc sees the request and through routing figures out that you want to call the Send method on the MyAppController class
  • Asp.Net Mvc sees that your method expects a string parameter named email and tries to find this information in the submitted form data using model binding
  • Asp.Net Mvc invokes the Send method with the found parameter value (if available)
  • ...

You do not provide quite enough context for me to be able to analyze what is wrong but my guess is that @Html.DropDownList("Emails", Model.GetEmails()) is generating something like <select name="Emails"> ....</select>. This means that when model binding is happening it is looking for submitted "email" input but finds nothing. Instead try something like @Html.DropDownList("email", Model.GetEmails()) to get it to work.

Semantically this is more correct anyways, because while the control displays emails (plural), a user actually interacts with it by selecting an email (singular). Think of it as if it was just a text box, you wouldn't name that in the plural.

I should note by the way, that you have several HUGE security holes here. By taking the email address as input into your method it seems like anyone can open up the developer tools in their browser and use your service to send emails to any email address! Spammers love to find unsecured services like this. A much better solution would be to have the value in the generated select list be an id for the user you want emailed, and in the Send method take the id as input. Also, Send should definitely not be accessible via Http GET (so put an [HttpPost] attribute on there!). If it allows GET, even if this is behind a login page, I can trick users who are logged in into visiting a form with an <img src="http://yoursite.com/MyApp/Send/[email protected]" /> and every time they visit the page someone will receive a spam email.

like image 139
George Mauer Avatar answered Feb 23 '23 16:02

George Mauer