Html.EnumDropDownListFor Set selected listitem based on enum variable's value

泄露秘密 提交于 2019-12-11 02:36:36

问题


This may be a duplicate, so I have indicated where my reading from this site has allowed me some progress...

I have a model defined as follows:

public enum RequestType
{
    [Display(Name = "Lovely Cold Beer")]
    Beer = 0,
    [Display(Name = "Warm Tea")]
    Tea = 1,
    [Display(Name = "Milky Coffee")]
    Coffee= 2
}

Based on the URL, I have a variable that will be used to automatically select the appropriate list item, e.g.

http://example.com/Request/Tea

will do this in the controller...

ViewBag.RequestType = RequestType.Tea.ToString();
return View("Index");

In my view I have a variable to read this value back, which then displays appropriate content:

if (ViewBag.RequestType != null)
{
    reqType = Enum.Parse(typeof(RequestType), ViewBag.RequestType);
}

In this view I create a drop down list using:

@Html.EnumDropDownListFor(model => model.RequestType, htmlAttributes: new { @onchange = "YadaYada();" })

This renders the list using the Display Name values defined for each Enum. What I need is to automatically select the appropriate list item when the page is rendered, that matches the value of reqType.

From my research I see that I can pass in the variable like so:

@Html.EnumDropDownListFor(model => model.RequestType, reqType.ToString(), htmlAttributes: new { @onchange = "YadaYada();" })

But this creates a new list item containing the enum value and not the display name, e.g.

Tea <-- This should not be created, instead 'Warm Tea' should be selected
Lovely Cold Beer
Warm Tea
Milky Coffee

My entire approach may be wrong as I'm new to MVC, but I'd welcome advice to fix it please! I don't understand why in the controller, using ToString on the enum value creates a different outcome to doing the same in the EnumDropDownListFor method.


回答1:


The second parameter (reqType.ToString()) of your EnumDropDownListFor() method is using the overload which adds an optionLabel (an option with a null value used for validation). It does not set the value of the selected option.

Model binding features of MVC work by binding to your property and since the default value of your RequestType is "Beer" , then that option will be selected.

You need to set the value of the property in the model before you pass the model to the view, for example (assumes you have a specific route for /Request/{request})

public ActionResult Request(RequestType request)
{
    var model = new MyModel
    {
        RequestType = request
    };
    return View(model);
}



回答2:


You must use html extensions. Example,

 public static string GetInputName<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
    {
        if (expression.Body.NodeType == ExpressionType.Call)
        {
            MethodCallExpression methodCallExpression = (MethodCallExpression)expression.Body;
            string name = GetInputName(methodCallExpression);
            return name.Substring(expression.Parameters[0].Name.Length + 1);

        }
        return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1);
    }

    private static string GetInputName(MethodCallExpression expression)
    {
        // p => p.Foo.Bar().Baz.ToString() => p.Foo OR throw...
        MethodCallExpression methodCallExpression = expression.Object as MethodCallExpression;
        if (methodCallExpression != null)
        {
            return GetInputName(methodCallExpression);
        }
        return expression.Object.ToString();
    }

    public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) where TModel : class
    {
        string inputName = GetInputName(expression);
        var value = htmlHelper.ViewData.Model == null
            ? default(TProperty)
            : expression.Compile()(htmlHelper.ViewData.Model);

        return htmlHelper.DropDownList(inputName, ToSelectList(typeof(TProperty), value.ToString()), htmlAttributes);
    }


来源:https://stackoverflow.com/questions/35800531/html-enumdropdownlistfor-set-selected-listitem-based-on-enum-variables-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!