14128

Formatting nullable decimal in RazorEngine

Question:

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 ?

Answer1:

The error above is from String.Format(). Interesting, as the documentation on <a href="https://msdn.microsoft.com/de-de/library/system.string.format.aspx" rel="nofollow">String.Format()</a> explains that null arguments should result in empty string.

For whatever reason Razor selects the overload <a href="https://msdn.microsoft.com/de-de/library/1ksz8yb7.aspx" rel="nofollow">String.Format(format, Object[])</a> to format your string. As your value is null.

I've created a <a href="https://gist.github.com/steven-r/eba9fda6d6e4b2c9e0ac" rel="nofollow">small example</a> 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...

<strong>EDIT (2)</strong>: Added the smarter workaround from <a href="https://stackoverflow.com/users/70140/moe-sisko" rel="nofollow">Moe Sisko</a>

<strong>EDIT</strong>: Rewrote to really answer the question ...

Recommend

  • Jenkins Pipeline Groovy: Read default parameter value from another job?
  • Richfaces editable dataTable not setting updated values in Bean
  • Using reflection to retrieve a value from a list
  • Why does this LinQ query not like chars?
  • EditText.SetText() changes my softkeyboard input type in a custom adapter
  • Reading old clipboard data in new program version in C#
  • SQLite UWP Error with Mobile EMulator Windows 10
  • Windows 10 Bluetooth Gatt Client ValueChanged issue
  • Remove an item from a list box causes a Catastrophic Failure?
  • Move to Web API RC, Get: Method not found: 'System.Web.Http.Services.DependencyResolver System.
  • Qt — pass events to multiple objects?
  • Thrift: Is it possible to do only serialization with the C (GLib) Thrift library?
  • Laravel : Integrity constraint violation
  • numpy 64bit support in PTVS and numpy System.Int64 casting
  • How do we generate stack trace in TOMCAT?
  • Appium MobileElement swipe returns unknown server error
  • What is this iOS exception with NSCFType?
  • Connecting bluetooth device to windows phone 8 application
  • Authentication failed with Azure Active Directory in Windows Phone
  • How do I access an unhandled exception in an MVC Error view?
  • Get data from AJAX - How to
  • Adding a button at the bottom of a table view
  • Counter field in MS Access, how to generate?
  • Fill an image in a square container while keeping aspect ratio
  • Javascript + PHP Encryption with pidCrypt
  • Websockets service method fails during R startup
  • Font Awesome Showing Box instead of Icons
  • Properly structure and highlight a GtkPopoverMenu using PyGObject
  • Akka Routing: Reply's send to router ends up as dead letters
  • AT Commands to Send SMS not working in Windows 8.1
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • Rails 2: use form_for to build a form covering multiple objects of the same class
  • Why can't I rebase on to an ancestor of source changesets if on a different branch?
  • How do I configure my settings file to work with unit tests?
  • apache spark aggregate function using min value
  • Is it possible to post an object from jquery to bottle.py?
  • Sorting a 2D array using the second column C++
  • Android Heatmap on canvas or ImageView
  • Conditional In-Line CSS for IE and Others?
  • Python/Django TangoWithDjango Models and Databases