0

I have a list of Deviation items getting from database. The list contains Severity which may be null. Thats why I made the SeverityNotNull property to transform null values to -1. BTW Severity can be 0-3.

I would like to show Deviations items in which each Severity should be a DropdownList line by line. And of course in the DropdownList the appropriate item should be selected.

my ViewModel is:

[MetadataType(typeof(DeviationMetaData))]
public partial class Deviation {
    public int SeverityNotNull {
        get { return Severity == null ? -1 : Severity.Value; }
    }
    ...
}

public class DeviationMetaData {
    public Nullable<int> Severity { get; set; }
    ...
}

public class DeviationViewModel {

    public Deviation Dev { set; get; }
    public IEnumerable<Deviation> Deviations {
        get {
            DeviationRepository dm = new DeviationRepository();
            return dm.GetAll;
        }
    }

    public DeviationViewModel() {
        WindowsIdentity current = WindowsIdentity.GetCurrent();
        string name = current.Name.Split(new[] { '\\' })[1];

        Dev = new Deviation { CreatedBy = name, CreatedDate = DateTime.Now };
    }
}

my Controller is:

public ActionResult Index() {
    IList<SelectListItem> items = new List<SelectListItem> {
        new SelectListItem{Text = "", Value = "-1"},
        new SelectListItem{Text = "Minor", Value = "1"},
        new SelectListItem{Text = "Major", Value = "2"},
        new SelectListItem{Text = "Critical", Value = "3"}
    };
    ViewBag.SelectSeverity = new SelectList(items, "Value", "Text");

    return View( new DeviationViewModel() );
}

my View is:

@model DeviationViewModel
    @using (Html.BeginForm()) {
            <table>
                <tr>
                    <th>
                        @Html.DisplayNameFor(model => model.Dev.Severity)
                    </th>
                </tr>
                @foreach (var item in Model.Deviations) {
                    <tr>
                        <td>
                            @Html.DropDownListFor(modelItem => item.SeverityNotNull, (SelectList)ViewBag.SelectSeverity)
                        </td>
                    </tr>
                }
            </table>
        </fieldset>
    }
</div>

I checked the SeverityNotNull values and they are correct. In the result there are the Dropdownlists, but nothing is selected. That is the problem. Could you give me some idea? Thanks.

3
  • If Severity can be null, what is the point of SeverityNotNull? Why do you need to transform null values to -1? Your going about this all wrong and it wont even bind on postback anyway Commented Oct 31, 2014 at 21:29
  • -1 is going to index of empty text in Dropdownlist. Obviously null cannot be an index. Why is it wrong? What is your idea anyway? Commented Oct 31, 2014 at 21:40
  • You don't need to do that. You have multiple other problems as well so I'll post an answer shortly. And view models should never contain database access code. Commented Oct 31, 2014 at 21:46

1 Answer 1

1

It is not necessary to create a SeverityNotNull property. A SelectList can contain an option with a null value that if selected will post back null. You have multiple other problems as well including using a foreach loop that will render <selects> with duplicate name attributes (wont bind on postback) and duplicate id attributes (invalid html).

Start by creating a view model to represent a Deviation

public class DeviationVM
{
  public int ID { get; set; }
  public int? Severity { get; set; }
  // other properties of the Deviation data model that you want to edit/display
}

Controller

public ActionResult Index()
{
  // Get your deviations and map to the view model
  List<DeviationVM> model = dm.GetAll().Select(d => new DeviationVM
  {
    ID = d.ID,
    Severity = d.Severity
  }).ToList();
  // create your select list (
  var severityList = new[] { new { ID = 1, Name = "Minor" }, new { ID = 2, Name = "Major" }, new { ID = 2, Name = "Critical" } };
  ViewBag.SeverityList = new SelectList(severityList, "ID", "Name");
  return View(model)
}

public ActionResult(List<DeviationVM> model)
{
  ...
}

View

@model List<DeviationVM>

@using (Html.BeginForm()) {
  ....
  for(int i = 0; i < Model.Count; i++)
  {
    @Html.HiddenFor(m => m[i].ID)
    @Html.DropDownListFor(m => m[i].Severity, (SelectList)ViewBag.SeverityList, "Text for null value")
  }

Note the use of the for loop which generates <select name="[0].Severity" ..> <select name="[1].Severity" ..> which are correctly named with indexers and will be bound on post back. Note also the use of the overload of @Html.DropDownListFor() which will generate the options as <option value>Text for null value</option> <option value="1">Minor</option> .... The first option does not have a value so if it is selected the value of property Severity will be null on postback.

Note also that if the value of property Severity is initiallt null then the first option will be selected by default. If the value is 2, then the 3rd option will be selected by default.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.