C# 模板中的RazorEngine扩展方法

C# 模板中的RazorEngine扩展方法,c#,razor,razorengine,C#,Razor,Razorengine,我正在使用剃须刀引擎: 我正在动态创建一个模型。我试图在模板中包含一个扩展方法,但它无法识别扩展类。我收到以下错误消息“string”不包含“ToUpperFirstLetter”的定义 模型创建 扩展类 剃刀解析 编辑 我还想在DynamicExpandooObject上创建一个扩展方法。查看模型中是否存在值。我收到以下错误消息System.Dynamic.ExpandooObject'不包含'HasValue'的定义 扩展类 编辑二 下面的工作将进入扩展方法 var o = new obje

我正在使用剃须刀引擎:

我正在动态创建一个模型。我试图在模板中包含一个扩展方法,但它无法识别扩展类。我收到以下错误消息“string”不包含“ToUpperFirstLetter”的定义

模型创建

扩展类

剃刀解析

编辑

我还想在DynamicExpandooObject上创建一个扩展方法。查看模型中是否存在值。我收到以下错误消息System.Dynamic.ExpandooObject'不包含'HasValue'的定义

扩展类

编辑二

下面的工作将进入扩展方法

var o = new object();
var bool = o.HasValue("value");
动态模型仍引发异常-RuntimeBinderException:“System.dynamic.ExpandooObject”不包含“HasValue”的定义


您所看到的问题是,您试图执行一个方法来处理这个字符串源,而实际上,Forename属性是动态的。我可以想象,如果你这样做:

@(((string)Model.Forename).ToUpperFirstLetter())
。。。这可能会奏效。这一切都取决于动态的使用。动态是通过后期绑定在运行时处理的,但在RazorEngine编译视图时,它试图静态链接需要字符串的方法,而您正在提供动态。编译器不知道名字是字符串

扩展方法也不能有动态第一个参数,例如:

public static string ToUpperFirsLetter(this dynamic source) { ... }
因为扩展方法在编译时解析为显式方法调用,但编译器不知道如何处理扩展方法中的动态第一个参数

编辑 根据您的回答,如果您希望实现这些类型可能为dynamic的扩展方法,您最好使用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);
  }
}

。。。不太理想,但它仍然是在动态上使用扩展方法的一种类型安全的方式。

您看到的问题是,您试图执行此字符串源的方法,而实际上,Forename属性是动态的。我可以想象,如果你这样做:

@(((string)Model.Forename).ToUpperFirstLetter())
。。。这可能会奏效。这一切都取决于动态的使用。动态是通过后期绑定在运行时处理的,但在RazorEngine编译视图时,它试图静态链接需要字符串的方法,而您正在提供动态。编译器不知道名字是字符串

扩展方法也不能有动态第一个参数,例如:

public static string ToUpperFirsLetter(this dynamic source) { ... }
因为扩展方法在编译时解析为显式方法调用,但编译器不知道如何处理扩展方法中的动态第一个参数

编辑 根据您的回答,如果您希望实现这些类型可能为dynamic的扩展方法,您最好使用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上使用扩展方法的一种类型安全的方式。

感谢您的回复。我还想在ExpandoObject上提供一个扩展方法,以查看模型是否包含值。有没有比上面描述的uve更容易实现的方法?请参见上面的编辑您遇到了相同的问题,但请参见编辑以获得替代解决方案。它仍然无法在动态对象上找到扩展方法。请参阅更新。谢谢,我对扩展方法和动态性越来越不自信了。您可能只能将其称为ExpandoObjectExtensions.HasValuevalue,key.Ye。它似乎是正确的。在动态对象上不可能使用扩展方法,解决方法是使用静态方法。感谢您的响应。我还想在ExpandoObject上提供一个扩展方法,以查看模型是否包含值。有没有比上面描述的uve更容易实现的方法?请参见上面的编辑您遇到了相同的问题,但请参见编辑以获得替代解决方案。它仍然无法在动态对象上找到扩展方法。请参阅更新。谢谢,我对扩展方法和动态性越来越不自信了。您可能只能将其称为ExpandoObjectExtensions.HasValuevalue,key.Ye。它似乎是正确的。在动态对象上不可能使用扩展方法,解决方法是使用静态方法。
dynamic model = new ExpandoObject();
var bool = model.HasValue("value");
@(((string)Model.Forename).ToUpperFirstLetter())
public static string ToUpperFirsLetter(this dynamic source) { ... }
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);
  }
}