Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nullables treated as non-nullable at runtime #33

Closed
farlee2121 opened this issue Oct 1, 2020 · 8 comments
Closed

Nullables treated as non-nullable at runtime #33

farlee2121 opened this issue Oct 1, 2020 · 8 comments

Comments

@farlee2121
Copy link

My model includes a DateTime? property

public class CampaignDesignerRequest
{
     //...
     public DateTime? CampaignStartDate { get; set; }
     //...
}

My view inherits the model

@inherits RazorEngineCore.RazorEngineTemplateBase<Fourstarzz.Accessors.ReportTemplates.Models.DesignedCampaign_RenderModel>

At write time, the intellisense recognizes CampaignStartDate as a nullable and shows an error hint if I try to run date string formatting without specifying .Value

Model.CampaignStartDate.Value.ToShortDateString()

However when I run the code, it gives me the error

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : 'System.DateTime' does not contain a definition for 'Value'

I've tested the same on other value types, like int and double, and get the same kind of error.

Versions

  • RazoreEngineCore 2020.9.1
  • .NET framework 4.8.

Any thoughts on potential causes?

@farlee2121
Copy link
Author

I think I may have a lead. Trying to use Linq select was causing a

Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type

This can be caused by using Linq on dynamic models. The non-generic template base uses dynamic as the type for the whole page model. https://github.com/adoconnection/RazorEngineCore/blob/master/RazorEngineCore/IRazorEngineTemplate.cs

I'm guessing there is some issue with dynamic typing going on here

@adoconnection
Copy link
Owner

adoconnection commented Oct 2, 2020

As I can see your view inherits different model DesignedCampaign_RenderModel whereas you looking at CampaignDesignerRequest

Have a look on this test:

public class TestModel
{
    public DateTime? DateTime { get; set; }

}

public class TestTemplate2 : RazorEngineTemplateBase<TestModel>
{
    public void Initialize(TestModel model)
    {
        this.Model = model;
    }
}
RazorEngine razorEngine = new RazorEngine();
DateTime? dateTime = DateTime.Now;

IRazorEngineCompiledTemplate<TestTemplate2> template = razorEngine.Compile<TestTemplate2>("DateTime: @Model.DateTime.Value.ToString()");

string actual = template.Run(instance => instance.Model = new TestModel()
{
        DateTime = dateTime
});

Assert.AreEqual("DateTime: " + dateTime, actual);

@adoconnection
Copy link
Owner

Also, I get same error as this if I do caching, see #28

@farlee2121
Copy link
Author

Woops, I copied the wrong model statement. CampaignDesignerRequest is actually a property on the other model, but I had been running experiments on a simplified version to make sure the parent object wasn't part of the issue.

I am caching as in issue #28. I'll have to test if the issue also happens with model-specific template caches.

@farlee2121
Copy link
Author

Ok. I ran a few tests. Using definitely typed templates as you did above, with model-specific caches, and by casting the cache solves the issue.

It also works to cast types within the template, though that could be a bit dangerous.

Definitely a good gotcha to have documented

@farlee2121
Copy link
Author

I'd be happy to contribute documentation if we want to promote it from an issue to the wiki or readme

@adoconnection
Copy link
Owner

you are welcome to push updates in description and wiki :)

@farlee2121
Copy link
Author

I'll try to push some changes this week

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants