6

アプリケーションで数値をフォーマットするために MVC 拡張機能を実装しました。これは、ここにあるコードに基づいています。そして以下の通り

public static MvcHtmlString DecimalBoxFor<TModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, double?>> expression, string format, object htmlAttributes = null)
{
    var name = ExpressionHelper.GetExpressionText(expression);   
    double? dec = expression.Compile().Invoke(html.ViewData.Model);
    var value = dec.HasValue ? (!string.IsNullOrEmpty(format) ? dec.Value.ToString(format) : dec.Value.ToString()): "";
    return html.TextBox(name, value, htmlAttributes);
}

Razor構文の次の行で呼び出すと

@Html.DecimalBoxFor(model => Model.PointAttributes[i].Data.Y,"0.000", new { @class = "span1 number" })

拡張機能の変数 'name' が空の文字列であるため、例外が発生します。var 名の行をこれに変更しようとしましたが、MVC 用にモデルをバインドするために必要な完全な 'Model.PointAttributes[i].Data.Y' ではなく、'Y' のプロパティ名しか表示されません。

var name = ((expression.Body is MemberExpression ?((MemberExpression)expression.Body).Member : ((MemberExpression)((UnaryExpression)expression.Body).Operand).Member)).Name;
4

5 に答える 5

9

この関数を使用してみてください:

    static public string GetExpressionText(LambdaExpression p)
    {
        if (p.Body.NodeType == ExpressionType.Convert || p.Body.NodeType == ExpressionType.ConvertChecked)
        {
            p = Expression.Lambda(((UnaryExpression)p.Body).Operand,
                p.Parameters);
        }
        return ExpressionHelper.GetExpressionText(p);
    }
于 2013-02-20T13:59:48.477 に答える
7

これは既知の動作です。ExpressionHelper私はその特定のケースを処理する独自のバージョンを書くことを考え出しました。今、2つのオプションがあります:

  1. NuGetパッケージを使用します。

    Install-Package Mariuzzo.Web.Mvc.Extras
    
  2. または、前述のExpressionHelperのソースコードを取得して、プロジェクトに接着します。

于 2013-02-21T14:35:45.733 に答える
3

ここに「ハイブリッド」のものがあります:)

    public static void AddModelError<TModel>(this ModelStateDictionary state, Expression<Func<TModel, object>> expression, string message)
    {
        LambdaExpression lambdaExpression = null;
        string fieldName = string.Empty;

        if (expression.Body.NodeType == ExpressionType.Convert || expression.Body.NodeType == ExpressionType.ConvertChecked)
        {
            lambdaExpression = Expression.Lambda(((UnaryExpression)expression.Body).Operand, expression.Parameters);
            fieldName = ExpressionHelper.GetExpressionText(lambdaExpression);
        } else {
            fieldName = ExpressionHelper.GetExpressionText(expression);
        }

        state.AddModelError(fieldName, message);
    }

これはよりコンパクトで、おそらくより良い解決策です:

https://stackoverflow.com/a/12689563/951001

于 2014-05-06T09:34:23.313 に答える
0

閉鎖されていることは知っていますが、記録のためです。

これはテンプレートでより適切に処理されるため、モデルで使用しているデータ型とテンプレートでの表現方法を指定できます (単一の責任)。また、MVC フレームワークを変更する必要はありません。

MSDN UiHint 属性

于 2013-08-23T11:29:55.140 に答える
0

null 許容型を使用せずに逃げることができれば、うまくいくようです (つまり、double の後の ? を削除するか、私の場合は decimal のように)。そう

Expression<Func<TModel, double?>> 

になる

Expression<Func<TModel, double>>.  

null 許容型を使用してステップスルーすると、式に convert() 関数が含まれていることがわかりますが、これが「問題」のようです。この関数を null 許容型でも機能させる方法に興味があると思います。

于 2012-06-03T05:43:33.127 に答える