2012-05-10 48 views
6

Zaimplementowałem rozszerzenie MVC do formatowania liczb w mojej aplikacji. Jest oparty na kodzie znalezionym pod numerem here. I przedstawia się następującoExpressionHelper.GetExpressionText (wyrażenie) nie zwraca nazwy mojej usługi

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); 
} 

Kiedy nazywają go z poniższej linii składni Razor

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

uzyskać wyjątek, ponieważ zmienna „name” w moim rozszerzenia jest pusty łańcuch. Próbowałem zmienić linię nazwy var do tego, ale to tylko daje mi nazwę właściwości "Y", a nie pełne "Model.PointAttributes [i] .Data.Y", które muszę związać model z powrotem dla MVC.

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

Odpowiedz

6

To znany zachowanie. Zorientowałem się, pisząc własną wersję ExpressionHelper, która obsługuje ten konkretny przypadek. Teraz masz dwie opcje:

  1. użyć pakietu Nuget:

    Install-Package Mariuzzo.Web.Mvc.Extras 
    
  2. lub po prostu chwycić the source code of the aforementioned ExpressionHelper i przykleić go do projektu.

+0

Dzięki @AarolamaBluenk, wezmę udział biorąc pod uwagę Twoją sugestię i ostatecznie się poprawię. Dzięki jeszcze raz. –

+0

Wpadliśmy na to i to działało idealnie dla nas. Dziękuję Ci! –

0

Jeśli można uciec bez użycia zerowalne typu wydaje się działać (czyli usunąć? Po dwu, lub jak w moim przypadku po przecinku). Więc

Expression<Func<TModel, double?>> 

staje

Expression<Func<TModel, double>>. 

Jeśli kroku przez to z wartości pustych typu w miejscu zobaczysz wyrażenie posiada funkcję konwertować(), który wydaje się być „problem”. Jestem pewien, że podobnie jak ja byłbyś zainteresowany tym, jak sprawić by ta funkcja działała również dla typów zerowych.

+0

Niestety musi być pustych rodzaj. – PlTaylor

8

Spróbuj użyć tej funkcji:

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); 
    } 
+1

Ta odpowiedź doprowadziła mnie do rozwiązania i stworzyłem/wydałem [Mariuzzo.Web.Mvc.Extras] (https://github.com/rmariuzzo/Mariuzzo.Web.Mvc.Extras) –

0

Wiem, że jest zamknięta, ale do protokołu;

To lepiej obsłużyć szablon, dzięki czemu można określić, jakiego typu danych używasz w modelu i jak jest reprezentowany w szablonie (pojedyncza responsywność). Nie trzeba również modyfikować środowiska MVC.

MSDN UiHint attribute

1

Tutaj 'hybryda' jeden :)

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); 
    } 

Ten jest bardziej zwarta i chyba lepszym rozwiązaniem:

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

Powiązane problemy