2013-01-06 60 views
-1

我已阅读了几个与我的问题相关的帖子,但没有解决我的特定问题。在运行时铸造

下面的类包含一些信息,这些信息将被传递给一个Razor引擎进行解析。

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

的ActionResult.ViewModel属性会认为,可能是因为我认为需要为我的看法是强类型的任何自定义类型的视图模型类的实例。

我会新的剃须刀引擎。

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

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

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

我的挑战是,我不知道如何把这种使用的ActionResult实例中的信息呈现方法在运行时可用。

,如果我硬代码的方法调用它做工精细...

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

,但我想我应该做的是越来越actionResult.ViewModel作为MyViewModelType或只是浇铸成MyViewModelType。但我不知道如何在运行时提供它的Type时调用razorEngine.Render()方法。

使用.NET 4.5

编辑...

我猜我想我可以做的是..

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

但这不起作用

+0

您需要使用反射,或者只是传递Object。 – SLaks

+0

razorEngine.Render(writer,(MyViewModelType)actionResult.ViewModel)有什么问题吗?我不知道我明白了什么是困难。 – Asik

+0

在剃须刀引擎上调用渲染方法时,模型参数需要与剃须刀视图的类型相同。我想我的缺点是如何在运行时将模型从对象类型转换为所需的自定义类型(M​​yViewModel)。 – JBeckton

回答

1

您可以使用反思实现您的需求:

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,但如果如上所述,库可能会在您的代码中创建错误,那么该库会得到更新。

+0

我同意,为什么我不能?期望的类型是在运行时确定的,那么正确地执行此操作的语法或表达式是什么? – JBeckton

+0

如果在运行时确定了“viewModel”的实际类型(来自您最初的问题,我认为您只是想将其预先确定的类型传递给泛型方法),那么我的问题中提供的方法将适用于您。 – Mir

+0

所以我不得不使用反射来得到这个呢? – JBeckton