Accept ViewData and ViewBag as Anonymous object
Closed this issue · 2 comments
Hi,
Found your library after coming from RazorLight for which I was so disappointed by the author who has been condescending and unpleasant relatively to a simple question I was asking.
I thought such library was quite difficult to write but I found yours is such easy to use and feature complete (views where you expect them to be, Layout, ViewImports)... Really, this is a great job. Thank you for this work.
I just wanted to let you know some simple addition I made to have a more straightforward ViewBag that I could set up as an anonymous object. Maybe this is something you will want to add in your lib. I did it with a static wrapper:
public static class RazorTemplateEngineWrapper
{
public async static Task<string> RenderAsync<TModel>([DisallowNull] string viewName, [DisallowNull] TModel model, [DisallowNull] object viewBag)
{
return await RazorTemplateEngine.RenderAsync(viewName, model, AnonymousTypeToDictionary(viewBag));
}
private static Dictionary<string, object> AnonymousTypeToDictionary(object obj)
{
var result = new Dictionary<string, object>();
if (obj != null)
{
foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(obj))
{
result.Add(pd.Name, pd.GetValue(obj));
}
}
return result;
}
}
Note that instead of Dictionary<string, object>, if the code was using a IDictionary<string, object?> it would be more exact I think.
I'm using it like this:
var body = await RazorTemplateEngineWrapper.RenderAsync("~/Views/EmailTemplates/EmailConfirm.text.cshtml", model, new { Message = message });
Thanks again.
Hi @cadilhac, glad to know that you find this library helpful and easy to use.
and for your suggestion, yes, it's a good to have feature and will be more intuitive for the users. I'm thinking of implementing it in the upcoming versions.
Keep supporting. Thanks!
Initially I planned to add this to the library but I'm hesitant to allow anonymous type in the argument. But I agree that it's much nicer to read.
However, the new C# features like Target-typed new expression and collection initializer allows us to simplify the dictionary initialization like:
var html = await RazorTemplateEngine.RenderAsync("/Views/ExampleView.cshtml", model, new()
{
["Value1"] = "1",
["Value2"] = "2"
});
Thanks for the suggestion anyway and people can use this extension method if they want!