adoconnection / RazorEngineCore

.NET6 Razor Template Engine
MIT License
565 stars 84 forks source link

Use JsonConverter (Newtonsoft) #92

Closed Cafnio closed 2 years ago

Cafnio commented 2 years ago

Hi there! First thanks for this awesome work!

I got all the Email Service implemented and working properly on other type of emails.

Yet, on a new type of email, the model contains a JSON string which I want to Deserialize and use the fields from it. Example:

On top of the .cshtml file, I have the following:

@using Newtonsoft.Json

then on the code itself.

@switch (Model.Purchase.Payment.PaymentType)
{
    case PaymentType.MULTIBANCO:
          var payData = JsonConvert.DeserializeObject<IfThenPayMbRefResponse>(Model.Purchase.PaymentData);
          @:<b>Entidade</b> : @payData?.Entity <br/>
          @:<b>Referência</b> : @payData?.Reference
          break;
    case PaymentType.CARD:
          @:Cartão Bancário
          break;
     case PaymentType.MBWAY:
          var payDataMbway = JsonConvert.DeserializeObject<IfThenPayMbwayResponse>(Model.Purchase.PaymentData);
          @:<b>Número de Telefone</b> : @payDataMbway.NrTelemovel <br/>
          break;

Yet, I recieve the error: "Could not load file or assembly 'Newtonsoft, Culture=neutral, PublicKeyToken=null'. System could not find the file"

I've tried the following, yet, the error persists:

builder.AddAssemblyReferenceByName("Newtonsoft");
builder.AddAssemblyReferenceByName("Newtonsoft.Json");
builder.AddAssemblyReferenceByName("Newtonsoft.Json.JsonConverter");
builder.AddAssemblyReference(Assembly.Load("Newtonsoft"));
builder.AddAssemblyReference(Assembly.Load("Newtonsoft.Json"));
builder.AddAssemblyReference(Assembly.Load("Newtonsoft.Json.JsonConverter"));
builder.AddUsing("Newtonsoft.Json");
builder.AddUsing("Newtonsoft");

Any idea to solve this issue?

adoconnection commented 2 years ago

Hi, the best way is to parse json outside of template and pass it as ready to use dynamic. If it is not possible, this is how you make it:

you need to go this way:

IRazorEngine razorEngine = new RazorEngine();
IRazorEngineCompiledTemplate template = razorEngine.Compile(Content, builder =>
{
    builder.AddAssemblyReference(typeof(JsonConvert));
    builder.AddUsing("Newtonsoft.Json");
});
string result = template.Run(new
{
    Json = "{a: 1}"
});

template:

@{
    dynamic json = JsonConvert.DeserializeObject(Model.Json);
}

<div>json: @json.a</div>
adoconnection commented 2 years ago

well, this also works for me

IRazorEngine razorEngine = new RazorEngine();
IRazorEngineCompiledTemplate template = razorEngine.Compile(Content, builder =>
{
    builder.AddAssemblyReference(typeof(JsonConvert));
});
string result = template.Run(new
{
    Json = "{a: 1}"
});
@using Newtonsoft.Json;

@{
    dynamic json = JsonConvert.DeserializeObject(Model.Json);
}

<div>json: @json.a</div>
Cafnio commented 2 years ago

Yep, got it working properly! Was adding the wrong AssemblyReference!

Thanks for the help :)