Formatting nullable decimal in RazorEngine

梦想与她 提交于 2019-12-25 02:04:01

问题


RazorEngine.dll version is 3.2.

Example code inside a razor engine template (cshtml file) :

      @foreach(var row in Model.Trades)
      {            
          <tr>          
             <td>
                @string.Format("{0:N2}",row.Amount)
             </td>
          </tr>
      }     

where row.Amount is defined in the Trades class as : public decimal? Amount;

The stack trace fromRazorEngine is :

> System.ArgumentNullException was caught   HResult=-2147467261  
> Message=Value cannot be null. Parameter name: args   Source=mscorlib  
> ParamName=args   StackTrace:
>        at System.String.Format(String format, Object[] args)
>        at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite
> site, T0 arg0, T1 arg1, T2 arg2)
>        at CompiledRazorTemplates.Dynamic.ccdceaafafffaefee.Execute()
>        at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext
> context) in
> c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Templating\TemplateBase.cs:line
> 126
>        at RazorEngine.Templating.TemplateService.Run(ITemplate template, DynamicViewBag viewBag) in
> c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Templating\TemplateService.cs:line
> 608
>        at RazorEngine.Templating.TemplateService.Parse(String razorTemplate, Object model, DynamicViewBag viewBag, String cacheName)
> in
> c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Templating\TemplateService.cs:line
> 439
>        at RazorEngine.Razor.Parse[T](String razorTemplate, T model, String cacheName) in
> c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Razor.cs:line
> 276

The error occurs when Amount is null. This is a workaround which seems to work ok :

@foreach(var row in Model.Trades)
{            
   <tr>          
      <td>
         @if (row.Amount != null)
         {                
           <text>@string.Format("{0:N4}", row.Amount)</text>
         }
     </td>
  </tr>
}

Any ideas, or at least a better workaround ? Thanks.

EDIT :

The workaround below is a bit more compact :

         <td>
            @(row.Amount == null ? "" : row.Amount.ToString("N4"))
         </td>

Does anyone know if Razor in MVC behaves in the same way ? Or is this behaviour specific to RazorEngine.dll ?


回答1:


The error above is from String.Format(). Interesting, as the documentation on String.Format() explains that null arguments should result in empty string.

For whatever reason Razor selects the overload String.Format(format, Object[]) to format your string. As your value is null.

I've created a small example at to explain the problem:

int? val = null;

// this one fails:
string template = "Hello @string.Format(\"{0:N4}\", Model.Value)! Welcome to Razor!";
string result = Razor.Parse(template, new { Value = val });

// this (ugly) workaround works:
string template = "Hello @(string.Format(\"{0:N4}{1}\", Model.Value, string.Empty))! Welcome to Razor!";
string result = Razor.Parse(template, new { Value = val });

// this (not so ugly) workaround works as well:
string template = "Hello @(string.Format(\"{0:N4}\", (Object)Model.Value))! Welcome to Razor!";
string result = Razor.Parse(template, new { Value = val });

Your workaround will work as well.

If this is a bug or a feature in Razor, I do not know...

EDIT (2): Added the smarter workaround from Moe Sisko

EDIT: Rewrote to really answer the question ...



来源:https://stackoverflow.com/questions/28868008/formatting-nullable-decimal-in-razorengine

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