Home > Software design >  ASP.NET Core MVC throws an exception on select
ASP.NET Core MVC throws an exception on select

Time:12-30

View model:

public class AppSettingsViewModel
{
    [Required, Display(Name = "Number of rows per page: ")]
    public int? NumberOfRows { get; set; }
    [Required, Display(Name = "Font size: ")]
    public int? FontSize { get; set; } = 14;
    [Required, Display(Name = "Font size unit: ")]
    public SelectList? FontSizeUnits { get; set; }
    public string? FontSizeUnit { get; set; } = "px";
}

Controller:

public List<Measure> Units = new ()
{
    new Measure { Unit = "cm", Def = "Centimeter" },
    new Measure { Unit = "mm", Def = "Millimeter" },
    new Measure { Unit = "Q", Def = "1/4 millimeter" },
    new Measure { Unit = "in", Def = "Inches" },
    new Measure { Unit = "pc", Def = "Picas" },
    new Measure { Unit = "pt", Def = "Points" },
    new Measure { Unit = "px", Def = "Pixels" },
    new Measure { Unit = "em", Def = "Parent's font size" },
    new Measure { Unit = "ex", Def = "Element's font size" },
    new Measure { Unit = "ch", Def = "Width of '0'" },
    new Measure { Unit = "rem", Def = "Root element's font size" },
    new Measure { Unit = "lh", Def = "Line height" },
    new Measure { Unit = "vh", Def = "Percent of viewport's height" },
    new Measure { Unit = "vw", Def = "Percent of viewport's width" },
    new Measure { Unit = "vmax", Def = "Percent of viewport's larger dimension" },
    new Measure { Unit = "vmin", Def = "Percent of viewport's smaller dimension" }
};

public struct Measure
{
    public string Unit;
    public string Def;
}

public HomeController(Data.MvcMovieContext context)
{
    db = context;
}

public IActionResult Settings()
{
    AppSettingsViewModel model = new()
    {
        NumberOfRows = 8, // REPLACE WITH DB VALUES!!!
        FontSizeUnits = new SelectList(Units, "Unit", "Def", "px"),
        FontSizeUnit = "px"
    };
    return View(model);
}

View (entire file):

@model KVL1.Models.AppSettingsViewModel
@{
    ViewData["Title"] = "Settings";
}
<div  style="max-width:50%">
    <form asp-action="Settings"  enctype="multipart/form-data">
        <div asp-validation-summary="ModelOnly" ></div>
        <div >
            <label asp-for="NumberOfRows" ></label><br />
            <input asp-for="NumberOfRows" type="range"  min="3" max="50" step="1" autofocus
                oninput="document.getElementById('NoRValue').innerHTML = this.value   ' rows';" />
            <label style="display:inline-block;margin-left:12px;position:relative;top:-7px" id="NoRValue">@Model.NumberOfRows rows</label>
            <span asp-validation-for="NumberOfRows" ></span>
            <p>The default value is 8 rows. Performance considerations limit the maximum number of rows to 50. 
                The minimum value is 3 rows. The Number of Rows setting affects only to the Movies list.</p>
        </div>
        <div >
            <div  style="width:3rem">
                <label asp-for="FontSize" ></label>
                <input asp-for="FontSize"  />
                <span asp-validation-for="FontSize" ></span>
            </div>
            <div  style=width:2rem>
                <label asp-for="FontSizeUnit" ></label>
                <select asp-for="FontSizeUnit" asp-items="Model.FontSizeUnits" >
                </select>
                <span asp-validation-for="FontSizeUnit" ></span>
            </div>
        </div>
        <div >
            <button type="submit"  style="width:10rem">Submit</button>
        </div>
    </form>
</div>
@section Scripts {
    @{
    await Html.RenderPartialAsync("_ValidationScriptsPartial");
    }
}

This is the exception I get:

System.NullReferenceException
HResult=0x80004003
Object reference not set to an instance of an object.

Source=Microsoft.AspNetCore.Mvc.ViewFeatures

StackTrace:

at Microsoft.AspNetCore.Mvc.Rendering.MultiSelectList.GetListItemsWithValueField()
at Microsoft.AspNetCore.Mvc.Rendering.MultiSelectList.GetListItems()
at Microsoft.AspNetCore.Mvc.Rendering.MultiSelectList.GetEnumerator()
at System.Collections.Generic.List1..ctor(IEnumerable1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at Microsoft.AspNetCore.Mvc.ViewFeatures.DefaultHtmlGenerator.GenerateGroupsAndOptions(String optionLabel, IEnumerable1 selectList, ICollection1 currentValues) at Microsoft.AspNetCore.Mvc.ViewFeatures.DefaultHtmlGenerator.GenerateSelect(ViewContext viewContext, ModelExplorer modelExplorer, String optionLabel, String expression, IEnumerable1 selectList, ICollection`1 currentValues, Boolean allowMultiple, Object htmlAttributes) at Microsoft.AspNetCore.Mvc.TagHelpers.SelectTagHelper.Process(TagHelperContext context, TagHelperOutput output) at Microsoft.AspNetCore.Razor.TagHelpers.TagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output) at Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.RunAsync(TagHelperExecutionContext executionContext) at AspNetCoreGeneratedDocument.Views_Home_Settings.<b__25_0>d.MoveNext() in C:\VS 2022\KVL1\Views\Home\Settings.cshtml:line 48

This exception was originally thrown at this call stack:
[External Code]

AspNetCoreGeneratedDocument.Views_Home_Settings.ExecuteAsync.AnonymousMethod__25_0() in Settings.cshtml

I can clearly see that none of the referenced variables are null and I have no clue as to where the exception originates, it seems to be deep in MSFT code.

Any help would be deeply appreciated!

CodePudding user response:

asp-items don' t like SelectLIst try this

 FontSizeUnits = Units.Select(i=> new SelectListItem {
Value=i.Unit,
Text=i.Def
}).ToList();

and fix model

 public List<SelectListItem> FontSizeUnits { get; set; }
  • Related