title: Getting selected option of SELECT from View back to Controller
body: <p>I have an ASP .Net Core 1.1 MVC web app. The app talks to a web API backend to read/write data to the data store.</p>
  
  <p>In the web app, I have an Edit page, where you can edit a record of a particular object. One of the fields in the record is a dropdownlist (i.e. an HTML  tag). My problem is I don't know how to get the selected option from the dropdownlist (in the View) back to the controller.</p>
  
  <p>To give you brief background, this web app will be used by real estate agents to manage their properties. To simply things, for now the property has a basic structure - an ID, and address and a "Property Type" (house, flat, office, etc)</p>
  
  <p>So I have these two models:</p>
  
  <pre><code>using System.Collections.Generic;
  using System.ComponentModel.DataAnnotations;
  using System.ComponentModel.DataAnnotations.Schema;
  
  namespace InspectionsData.Models
  {
      public partial class PropertyType
      {
          [Key]
          [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
          public int Id { get; set; }
          public string PropertyTypeName { get; set; } // e.g. house, flat, office, etc.
      }
  }
  </code></pre>
  
  <p>and</p>
  
  <pre><code>using System;
  using System.ComponentModel.DataAnnotations;
  using System.ComponentModel.DataAnnotations.Schema;
  
  namespace InspectionsData.Models
  {
      [Table("property")]
      public class Property
      {
  
          [Key]
          [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
          public int? Id { get; set; }
          public string Street { get; set; }
          public string City { get; set; }
          public string Region { get; set; }
          public string Country { get; set; }
          public int? PropertyTypeId { get; set; }
          [ForeignKey("PropertyTypeId")]
          public PropertyType PropertyType { get; set; }
      }
  }
  </code></pre>
  
  <p>I then created a ViewModel so that I can feed both of the above models to the view:</p>
  
  <pre><code>using InspectionsData.Models;
  using Microsoft.AspNetCore.Mvc.Rendering;
  
  namespace InspectionsTestClient.ViewModels
  {
      public class PropertyIndexViewModel
      {
          public Property Property { get; set; }
          public SelectList PropertyTypes { get; set; }
      }
  }
  </code></pre>
  
  <p>Then I have a controller which populates the view:</p>
  
  <pre><code>// GET: Property/Edit/5
          public async Task&lt;ActionResult&gt; Edit(int id)
          {
              string apiUrl = "http://localhost:50082/api/";
  
              if (!ModelState.IsValid)
              {
                  return BadRequest(ModelState);
              }
  
              //Read property from Web API            
              string url = apiUrl + "Properties/" + id.ToString();
              HttpResponseMessage responseMessage = await client.GetAsync(url);
              if (responseMessage.IsSuccessStatusCode)
              {
                  var responseData = responseMessage.Content.ReadAsStringAsync().Result;
                  var prop = Newtonsoft.Json.JsonConvert.DeserializeObject&lt;Property&gt;(responseData);
                  if (prop == null)
                  {
                      return NotFound();
                  }
  
                  List&lt;PropertyType&gt; propertyTypes = null;
                  url = apiUrl + "PropertyTypes";
                  responseMessage = await client.GetAsync(url);
                  if (responseMessage.IsSuccessStatusCode)
                  {
                      responseData = responseMessage.Content.ReadAsStringAsync().Result;
                      propertyTypes = Newtonsoft.Json.JsonConvert.DeserializeObject&lt;List&lt;PropertyType&gt;&gt;(responseData);
                  }
  
                  PropertyIndexViewModel vm = new PropertyIndexViewModel()
                  {
                      Property = prop,
                      PropertyTypes = new SelectList(propertyTypes, "Id", "PropertyTypeName")
                  };
  
                  return View(vm);
              }
  
              return View("Error");
          }
  </code></pre>
  
  <p>I know it's inefficient in making two calls to the API - one to get the property and one to get the list of Property Types - I will improve this later, but for now that's how it is...
  and the view:</p>
  
  <pre><code>@model InspectionsTestClient.ViewModels.PropertyIndexViewModel
  
  @{
      ViewData["Title"] = "Edit";
  }
  
  @{
      Layout = "_Layout";
  }
  
  &lt;h2&gt;Edit&lt;/h2&gt;
  
  @Html.ValidationSummary();
  
  &lt;form asp-action="Edit"&gt;
      &lt;div class="form-horizontal"&gt;
          &lt;h4&gt;Property&lt;/h4&gt;
          &lt;hr /&gt;
          &lt;div asp-validation-summary="ModelOnly" class="text-danger"&gt;&lt;/div&gt;
          &lt;input type="hidden" asp-for="Property.Id" /&gt;
          &lt;div class="form-group"&gt;
              &lt;label asp-for="Property.Street" class="col-md-2 control-label"&gt;&lt;/label&gt;
              &lt;div class="col-md-10"&gt;
                  &lt;input asp-for="Property.Street" class="form-control" /&gt;
                  &lt;span asp-validation-for="Property.Street" class="text-danger"&gt;&lt;/span&gt;
              &lt;/div&gt;
          &lt;/div&gt;
          &lt;div class="form-group"&gt;
              &lt;label asp-for="Property.City" class="col-md-2 control-label"&gt;&lt;/label&gt;
              &lt;div class="col-md-10"&gt;
                  &lt;input asp-for="Property.City" class="form-control" /&gt;
                  &lt;span asp-validation-for="Property.City" class="text-danger"&gt;&lt;/span&gt;
              &lt;/div&gt;
          &lt;/div&gt;
          &lt;div class="form-group"&gt;
              &lt;label asp-for="Property.Region" class="col-md-2 control-label"&gt;&lt;/label&gt;
              &lt;div class="col-md-10"&gt;
                  &lt;input asp-for="Property.Region" class="form-control" /&gt;
                  &lt;span asp-validation-for="Property.Region" class="text-danger"&gt;&lt;/span&gt;
              &lt;/div&gt;
          &lt;/div&gt;
          &lt;div class="form-group"&gt;
              &lt;label asp-for="Property.Country" class="col-md-2 control-label"&gt;&lt;/label&gt;
              &lt;div class="col-md-10"&gt;
                  &lt;input asp-for="Property.Country" class="form-control" /&gt;
                  &lt;span asp-validation-for="Property.Country" class="text-danger"&gt;&lt;/span&gt;
              &lt;/div&gt;
          &lt;/div&gt;
          &lt;div class="form-group"&gt;
              &lt;label asp-for="Property.PropertyType" class="col-md-2 control-label"&gt;&lt;/label&gt;
              &lt;div class="col-md-10"&gt;
                  &lt;select asp-for="Property.PropertyType" asp-items="@Model.PropertyTypes"&gt;&lt;/select&gt;
              &lt;/div&gt;
          &lt;/div&gt;
          &lt;div class="form-group"&gt;
              &lt;div class="col-md-offset-2 col-md-10"&gt;
                  &lt;input type="submit" value="Save" class="btn btn-default" /&gt;
              &lt;/div&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  &lt;/form&gt;
  
  &lt;div&gt;
      &lt;a asp-action="Index"&gt;Back to List&lt;/a&gt;
  &lt;/div&gt;
  
  @section Scripts {
      @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
  }
  </code></pre>
  
  <p>When the user clicks the SAVE button on the form, it posts back to another controller action:</p>
  
  <pre><code>// POST: Property/Edit/5
          [HttpPost]
          [ValidateAntiForgeryToken]
          public async Task&lt;ActionResult&gt; Edit(int id, Property prop)
          {
              try
              {
                  if (ModelState.IsValid)
                  {
                      string apiUrl = "http://localhost:50082/api/";                    
                      string url = apiUrl + "properties/" + id.ToString();
                      string jsonInString = JsonConvert.SerializeObject(prop);                    
                      HttpContent content = new StringContent(jsonInString, Encoding.UTF8, "application/json");
                      HttpResponseMessage responseMessage = await client.PutAsync(url, content);
                      if (responseMessage.IsSuccessStatusCode)
                      {
                          return RedirectToAction("Index");
                      }                    
                  }
  
                  return View();
              }
  
              catch
              {
                  return View();
              }
          }
  </code></pre>
  
  <p>So this controller action posts the updated property to the web API. The problem is that, everything works 100% until it gets to this final controller action - if I inspect the "prop" parameter, it contains all the modifications made, but it does not contain the selected PopertyType - how can I return the selected PropertyType from the view back to the controller?
  Thanks...</p>