RazorEngine扩展方法在模板中
我使用的是Razor引擎:https://github.com/Antaris/RazorEngine。
我正在动态创建一个模型。 我试图在模板中包含一个扩展方法,但它会识别扩展类。 我收到以下错误消息“ '字符串'不包含'ToUpperFirstLetter'的定义 ”
模型创建
dynamic model = new ExpandoObject();
((IDictionary<string, object>)model).Add("Forename", "john");
模板
@using Namespace.Extensions
@{
ViewBag.Title = "Title";
}
Hello @Model.Forename.ToUpperFirstLetter()
扩展类
namespace Namespace.Extensions
{
public static class StringExtensions
{
public static string ToUpperFirstLetter(this string source)
{
return ....removed for abbreviation
}
}
}
剃刀分析
ITemplate template = Razor.Resolve(template, model);
string result = template.Run(new ExecuteContext());
编辑
我也想在Dynamic ExpandoObject上创建一个扩展方法。 查看模型中的值是否存在。 我收到以下错误消息“ System.Dynamic.ExpandoObject”不包含'HasValue'的定义 “
扩展类
public static class ExpandoObjectExtensions
{
public static bool HasValue(this ExpandoObject source, string key)
{
return ((IDictionary<String, object>)source).ContainsKey(key);
}
}
扩展使用
@if(Model.HasValue("Hello"))
{
@Model.Hello
}
编辑两个
下面的工作,并进入扩展方法
var o = new object();
var bool = o.HasValue("value");
动态模型仍会抛出异常 - RuntimeBinderException:'System.Dynamic.ExpandoObject'不包含'HasValue'的定义
dynamic model = new ExpandoObject();
var bool = model.HasValue("value");
你看到的问题是你试图执行方法ToUpperFirstLetter(this string source)
,实际上, Forename
属性是dynamic
。 我会想象如果你做了这样的事情:
@(((string)Model.Forename).ToUpperFirstLetter())
...它可能会工作。 这完全取决于dynamic
的使用。 动态是通过后期绑定在运行时处理的,但由于RazorEngine正在编译您的视图,因此它试图静态链接期望您提供动态字符串的方法。 编译器不知道Forename
是一个字符串。
你也不能有一个扩展方法的dynamic
第一个参数,例如:
public static string ToUpperFirsLetter(this dynamic source) { ... }
因为扩展方法在编译时被解析为显式方法调用,但编译器不知道如何处理扩展方法中的动态第一个参数。
编辑基于你的回应,如果你想实现这种类型的动态可能是类型的扩展方法,你会更好地使用object
和类型的测试,例如:
public static class StringExtensions
{
public static string ToUpperFirstLetter(this object val)
{
string str = val as string;
if (string.IsNullOrWhitespace(str)) return str;
return str.Substring(0, 1).ToUpper() + str.Substring(1);
}
}
public static class ExpandoObjectExtensions
{
public static bool HasValue(this object val, string key)
{
var expando = val as ExpandoObject;
if (expando == null) return false;
return ((IDictionary<string, object>)expando).ContainsKey(key);
}
}
...不理想,但它仍然是一种在dynamic
中使用扩展方法的类型安全方法。
上一篇: RazorEngine extension methods in a template
下一篇: RazorEngine layouts