2

真的很简单的问题。

我有一个 MVC 视图,它显示一个 Nullable Bool,例如,

Html.CheckBoxFor(model=>model.NullableBoolHere, Model.NullableBoolHere, 

我想创建一个新的 html 助手,它将接受这种类型,然后转换

Null || False => False
True => True

所以我有以下

public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool?>> expression, object htmlAttributes, bool disabled)
    {
        IDictionary<string, object> values = new RouteValueDictionary(htmlAttributes);

        if (disabled)
            values.Add("disabled", "true");

        Expression<Func<TModel, bool>> boolExpression = CONVERT_TO_BOOL_HERE(expression);


        return htmlHelper.CheckBoxFor(expression, values);
    }

任何帮助表示赞赏,我知道我将不得不使用递归来复制表达式,但只是不确定如何导航表达式本身,找到 bool?,转换为 bool。

4

4 回答 4

1

您可以使用以下代码:

var body = Expression.Coalesce(expression.Body, Expression.Constant(false));
var boolExpression = (Expression<Func<TModel, bool>>)
    Expression.Lambda(body, expression.Parameters.First());

其他答案的优点是它不编译第一个表达式,它只是包装它。生成的表达式类似于以下代码创建的表达式:

m => m.NullableBoolHere ?? false

现场检查

于 2013-01-16T11:05:56.903 回答
1

所以,最后,我能找到的唯一方法就是解决布尔问题?自己进入一个布尔值,然后通过传入正确的名称等返回一个“正常”复选框。

不过,这确实是一种享受,所以一切都很好。如果您确实知道获得正确 ParameterName 的更好方法,那将是很高兴听到。

public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool?>> expression, object htmlAttributes, bool disabled)
    {
        IDictionary<string, object> values = new RouteValueDictionary(htmlAttributes);

        if (disabled)
            values.Add("disabled", "true");

        //Compile the expression to get the value from it.
        var compiled = expression.Compile().Invoke(htmlHelper.ViewData.Model);
        bool checkValue = compiled.HasValue ? compiled.Value : false; //evaluate the compiled expression

        //Get the name of the id we should use
        //var parameterName = ((MemberExpression)expression.Body).Member.Name; // only gives the last part
        string parameterName = expression.Body.ToString().Replace("model.", "");//.Replace(".", HtmlHelper.IdAttributeDotReplacement);

        //Return our 'hand made' checkbox
        return htmlHelper.CheckBox(parameterName, checkValue, values);
    }
于 2013-02-12T10:43:23.773 回答
0

我想仅仅将表达式转换为另一种类型是不够的,MVC 使用表达式是有原因的,所以我怀疑它需要检查给定的表达式并对其应用一些魔法。

您可以创建一个执行转换的新表达式,如下所示:

 Expression<Func<TModel, bool>> boolExpression = 
        T => expression.Compile()(T).GetValueOrDefault(false);

但正如我所说,我怀疑这还不够,MVC 可能想要检查表达式中的模型成员等。

于 2013-01-16T11:01:10.353 回答
0

这个怎么样:

 Expression<Func<TModel, bool>> boolExpression = model =>
        {
             bool? result = expression.Compile()(model);

             return result.HasValue ? result.Value : false;
        };

这样你包装原始表达式,你可以从 bool? 布尔值。

它解决了你的问题吗?

于 2013-01-16T11:04:28.473 回答