在运行时进行转换

时间:2013-01-06 16:44:51

标签: asp.net razor

我已阅读了几篇与我的问题相关的帖子,但都没有解决我的特定问题。

下面的类包含一些信息,这些信息将通过Razor引擎进行解析。

public class ActionResult
{
    public object ViewModel { get; set; }
    public string View { get; set; }
}

ActionResult.ViewModel属性将包含一个视图模型类的实例,该类可以是我的视图所需的任何自定义类型,因为我的视图是强类型的。

我会把剃刀引擎弄新来。

var razorEngine = new RazorEngine(razorScriptFile, _moduleResult.ModuleContext, "");

然后调用一个render方法,它的签名是......

public void Render<T>(TextWriter writer, T model){}

我遇到的挑战是,我不确定如何使用运行时可用的actionResult实例中的信息来调用此render方法。

如果我对方法调用进行硬编码就可以正常工作......

razorEngine.Render<MyViewModelType>(writer, actionResult.ViewModel);

但我想我应该做的是将actionResult.ViewModel作为MyViewModelType或仅将其转换为MyViewModelType。但是我不确定如何在运行时提供它的类型时调用razorEngine.Render()方法。

使用.Net 4.5

编辑...

我想我认为我能做的就是......

Type type = actionResult.ViewModel.GetType();
var model = actionResult.ViewModel as type;

但这不起作用

1 个答案:

答案 0 :(得分:1)

您可以使用Reflection来实现您的需求:

var viewModel = actionResult.ViewModel;
var method = typeof (RazorEngine).GetMethod("Render").
    MakeGenericMethod(viewModel.GetType());
method.Invoke(razorEngine, new[] {writer, viewModel});

但正如评论中所说,为什么不能将viewModel投射到您想要的类型?

编辑:由于Render的唯一其他重载是非通用Render(TextWriter),您可以使用以下代码:

var method = typeof (RazorEngine).GetMethods().
    Single(m => m.Name == "Render" && m.ContainsGenericParameters).
    MakeGenericMethod(viewModel.GetType());

但是我建议您通过添加其他检查来使代码更安全。如果在新版本Render中获取具有泛型参数的新重载,则上述代码将引发异常。您可以使用First代替Single,但如果如上所述,库可以获得更新,则可能会在您的代码中产生错误。