在 RazorEngine 中格式化可为空的十进制 [英] Formatting nullable decimal in RazorEngine

查看:58
本文介绍了在 RazorEngine 中格式化可为空的十进制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

RazorEngine.dll 版本为 3.2.

剃刀引擎模板(cshtml 文件)中的示例代码:

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

其中 row.Amount 在 Trades 类中定义为:公共小数点?数量;

来自 RazorEngine 的堆栈跟踪是:

<代码>>System.ArgumentNullException 被捕获 HResult=-2147467261>Message=Value 不能为空.参数名称:args Source=mscorlib>ParamName=args 堆栈跟踪:>在 System.String.Format(String format, Object[] args)>在 System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite>站点,T0 arg0,T1 arg1,T2 arg2)>在 CompiledRazorTemplates.Dynamic.ccdceaafafffaefee.Execute()>在 RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext>上下文)在>c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Templating\TemplateBase.cs:line>126>在 RazorEngine.Templating.TemplateService.Run(ITemplate template, DynamicViewBag viewBag) 中>c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Templating\TemplateService.cs:line>608>在 RazorEngine.Templating.TemplateService.Parse(String razorTemplate, Object model, DynamicViewBag viewBag, String cacheName)>在>c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Templating\TemplateService.cs:line>439>在 RazorEngine.Razor.Parse[T](String razorTemplate, T model, String cacheName) 中>c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Razor.cs:line>276

当金额为空时发生错误.这是一种似乎可以正常工作的解决方法:

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

任何想法,或者至少是更好的解决方法?谢谢.

下面的解决方法更紧凑:

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

有谁知道 MVC 中的 Razor 是否有同样的行为?还是此行为特定于 RazorEngine.dll?

解决方案

以上错误来自 String.Format().有趣的是,关于 String.Format() 说明空参数应该导致空字符串.

无论出于何种原因,Razor 都会选择重载 String.Format(format, Object[]) 格式化您的字符串.由于您的值为 null.

我创建了一个小例子来解释问题:>

int?val = 空;//这个失败了:string template = "Hello @string.Format(\"{0:N4}\", Model.Value)!欢迎使用 Razor!";字符串结果 = Razor.Parse(template, new { Value = val });//这个(丑陋的)解决方法有效:string template = "Hello @(string.Format(\"{0:N4}{1}\", Model.Value, string.Empty))!欢迎使用 Razor!";字符串结果 = Razor.Parse(template, new { Value = val });//这个(不那么难看)的解决方法也有效:string template = "Hello @(string.Format(\"{0:N4}\", (Object)Model.Value))!欢迎使用 Razor!";字符串结果 = Razor.Parse(template, new { Value = val });

您的解决方法同样有效.

如果这是 Razor 中的错误或功能,我不知道...

编辑 (2):从 Moe Sisko 中添加了更智能的解决方法>

编辑:重写以真正回答问题......

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 ?

解决方案

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 ...

这篇关于在 RazorEngine 中格式化可为空的十进制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆