skip to Main Content

I have an ASP.NET web app running in an Azure app service.

After doing a profiler trace, I noticed these three .NET exceptions:

Requested value 'Asc' was not found.

Asc is not a valid value for SortOrder.

The parameter conversion from type 'System.String' to type 'Enums.SortOrder' failed. See the inner exception for more information.

They all have this stack trace:

mscorlib.ni![COLD] System.Enum+EnumResult.SetFailure
mscorlib.ni!System.Enum.Parse
system.ni!
system.web.http!System.Web.Http.ValueProviders.ValueProviderResult.ConvertSimpleType
system.web.http!System.Web.Http.ValueProviders.ValueProviderResult.UnwrapPossibleListType
system.web.http!System.Web.Http.ValueProviders.ValueProviderResult.ConvertTo
system.web.http!System.Web.Http.ModelBinding.Binders.TypeConverterModelBinder.BindModel
system.web.http!System.Web.Http.Controllers.HttpActionContextExtensions.Bind
system.web.http!System.Web.Http.ModelBinding.Binders.CompositeModelBinder.BindModel
system.web.http!System.Web.Http.ModelBinding.ModelBinderParameterBinding.ExecuteBindingAsync
system.web.http!System.Web.Http.Controllers.HttpActionBinding+<ExecuteBindingAsyncCore>d__12.MoveNext
mscorlib!System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start
system.web.http!System.Web.Http.Controllers.HttpActionBinding.ExecuteBindingAsyncCore
system.web.http!System.Web.Http.Controllers.HttpActionBinding.ExecuteBindingAsync
system.web.http!System.Web.Http.Controllers.ActionFilterResult+<ExecuteAsync>d__5.MoveNext
mscorlib!System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[System.__Canon].Start
system.web.http!System.Web.Http.Controllers.ActionFilterResult.ExecuteAsync
system.web.http!System.Web.Http.ApiController.ExecuteAsync
system.web.http!System.Web.Http.Dispatcher.HttpControllerDispatcher+<SendAsync>d__15.MoveNext
mscorlib!System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[System.__Canon].Start
system.web.http!System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync
system.net.http.ni!
system.web.http!System.Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync
system.net.http.ni!
autofac.integration.webapi!Autofac.Integration.WebApi.CurrentRequestHandler.SendAsync
system.net.http.ni!
Rend.invgen.invoicegateway.api!Rend.invgen.InvoiceGateway.Api.Handlers.RequestResponseLogHandler.SendNextAsync
Rend.invgen.invoicegateway.api!Rend.invgen.InvoiceGateway.Api.Handlers.RequestResponseLogHandler+<>c__DisplayClass0_0.<SendAsync>b__0
mscorlib.ni!System.Threading.Tasks.Task.Execute
mscorlib.ni!System.Threading.Tasks.Task.ExecutionContextCallback
mscorlib.ni!System.Threading.ExecutionContext.Run
mscorlib.ni!System.Threading.Tasks.Task.ExecuteWithThreadLocal
mscorlib.ni!System.Threading.Tasks.Task.ExecuteEntry
mscorlib.ni!System.Threading.Tasks.SynchronizationContextTaskScheduler.PostCallback
system.web.ni!
mscorlib.ni!System.Threading.Tasks.Task.Execute
mscorlib.ni!System.Threading.Tasks.Task.ExecutionContextCallback
mscorlib.ni!System.Threading.ExecutionContext.Run
mscorlib.ni!System.Threading.Tasks.Task.ExecuteWithThreadLocal
mscorlib.ni!System.Threading.Tasks.Task.ExecuteEntry
mscorlib.ni!System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem
mscorlib.ni!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback

My action method which is causing this issue looks like this:

public async Task<IHttpActionResult> GetAsync(SortOrder sort = SortOrder.Ascending)
{
    // sort something
}

This action method is called using arguments such as Asc.

Even though this seems to cause .NET exceptions, the default value of Ascending gets used if it can’t bind a value.

My question is, why am I unable to view the Requested value Asc was not found exceptions locally?

When I run the app locally and pass Asc and Desc, no Exceptions are thrown, and I can’t see any Exceptions in the Debug window either.

2

Answers


  1. I have reproduced and able to resolve, please follow the below steps

    • Below is the folder structure

    enter image description here

    ActionModel.cs

    • To bind the data to the view we are using action model
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Threading.Tasks;
    using System.Web.Http;
    using System.Web.Mvc;
    
    namespace MVC_Sort
    {
        public class ActionModel
        {
            public ActionModel()
            {
                ActionsList = new List<SelectListItem>();
            }
            [Display(Name="Names")]
            public int ActionId { get; set; }
    
            public IEnumerable<SelectListItem> ActionsList { get; set; }       
        }
    }
    

    ActionType.cs

    • A list of Enum to display in sorted order
    namespace MVC_Sort
    {
        public enum ActionType
        {
            MMM = 1,
            RRR = 2,
            AAA = 3,
            JJJ = 4,
            EEE = 5,
            SSS = 6,
            HHH = 7
        }
    
    }
    

    ActionTypeModel.cs

    • In view it is used to display the Enum values and label names in the output
    using System.ComponentModel.DataAnnotations;
    namespace MVC_Sort
    {
        public class ActionTypeModel
        {
            [Display(Name = "Names")]
            public int ActionId { get; set; }
            public ActionType ActionTypeList { get; set; }
        }
    }
    

    HomeController.cs

    • The Action method in the HomeController is executed when requested
    namespace MVC_Sort.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                ActionModel model = new ActionModel();
                IEnumerable<ActionType> actionTypes = Enum.GetValues(typeof(ActionType))
                                                           .Cast<ActionType>();
    
                var res= actionTypes.OrderBy(enm => enm.ToString()).ToArray();
    
                model.ActionsList = from action in res
                                    select new SelectListItem
                                    {
                                        Text = action.ToString(),
                                        Value = ((int)action).ToString()
                                    };
    
                return View(model);
            }
    
            public ActionResult ActionTypes()
            {
                ActionTypeModel model = new ActionTypeModel();
                return View(model);
            }
        }
    }
    

    Index.cshtml

    • It is the Html page displayed when executed
    model MVC_Sort.ActionModel
    @{
        ViewBag.Title = "Index";
    }
    
    @Html.LabelFor(model=>model.ActionId)
    @Html.DropDownListFor(model=>model.ActionId, Model.ActionsList)
    

    Extension.cs

    • It is used to fetch or retrieve Enum values from ActionType
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Web.Mvc;
    using System.Web.Mvc.Html;
    
    namespace MVC_Sort
    {
        public static class Extension
        {
    
            public static MvcHtmlString EnumDropDownListFor<TModel, TProperty, TEnum>(this HtmlHelper<TModel> htmlHelper,
                                                                                        Expression<Func<TModel, TProperty>> expression, 
                                                                                        TEnum selectedValue)
            {
                IEnumerable<TEnum> values = Enum.GetValues(typeof(TEnum))
                                            .Cast<TEnum>();
    
                IEnumerable<SelectListItem> items = from value in values
                                                    select new SelectListItem()
                                                    {
                                                        Text = value.ToString(),
                                                        Value = value.ToString(),
                                                        Selected = (value.Equals(selectedValue))
                                                    };
    
                return SelectExtensions.DropDownListFor(htmlHelper,expression, items);
            }
        }
    }
    
    • After the above steps Click on debug => Start debugging. After it will open the below one in the browser in Sorted order

    enter image description here

    Login or Signup to reply.
  2. By default, Binding an Enum expects the integer value corresponding to the value.

    If you want to supply a string value, you must tell the modelbinder that by adding an attribute to your Enum type declaration, like this:

    [ModelBinder(BinderType = typeof(EnumModelBinder))]
    public enum SortOrder
    {
    }
    

    or you can add an attribute to your property in the model, like this:

    [BindProperty(BinderType = typeof(EnumModelBinder))]
    public SortOrder MySortOrder {get;set;}
    

    Now the modelbinder should be able to handle strings. Of course the strings must match the enum values exact.

    BTW: Modelbinding, that fails, does not throw exceptions, it simply ignores the values, meaning properties will get their default values.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search