迭代ASP.NET MVC视图以查找支持特定模型类型的所有视图

时间:2014-10-31 18:06:16

标签: c# asp.net asp.net-mvc razor reflection

我想获得支持呈现特定模型类型的所有视图的列表。

伪代码:

IEnumerable GetViewsByModelType(Type modelType)
{
   foreach (var view in SomeWayToGetAllViews())
   {
      if (typeof(view.ModelType).IsAssignableFrom(modelType))
      {
         yield return view; // This view supports the specified model type
      }
   }
}

换句话说,鉴于我有一个MyClass模型,我想找到支持渲染它的所有视图。即@model类型为MyClass的所有视图,或其继承链中的类型。

2 个答案:

答案 0 :(得分:8)

根据我的调查结果,编译的视图不包含在大会中,所以它不会成为公园反射中的一个步行。

在我看来,最好的办法是列出.cshtml剃刀视图,然后使用BuildManager类编译类型,这样就可以获得Model属性类型。< / p>

以下是查找具有@Model类型的LoginViewModel的所有Razor视图的示例:

var dir = Directory.GetFiles(string.Format("{0}/Views", HostingEnvironment.ApplicationPhysicalPath), 
    "*.cshtml", SearchOption.AllDirectories);

foreach (var file in dir)
{
    var relativePath = file.Replace(HostingEnvironment.ApplicationPhysicalPath, String.Empty);

    Type type = BuildManager.GetCompiledType(relativePath);

    var modelProperty = type.GetProperties().FirstOrDefault(p => p.Name == "Model");

    if (modelProperty != null && modelProperty.PropertyType == typeof(LoginViewModel))
    {
        // You got the correct type
    }
}

答案 1 :(得分:0)

根据@Faris Zacina 的回答,我想出了这个代码:

string[] GetViews<TModel>(string virtualPath)
{
    var physicalPath = HostingEnvironment.MapPath(virtualPath);
    
    return Directory
        .GetFiles(physicalPath, "*.cshtml", SearchOption.TopDirectoryOnly)
        .Select(viewPath => virtualPath + "/" + Path.GetFileName(viewPath))
        .Where(virtualViewPath => BuildManager.GetCompiledType(virtualViewPath).GetProperty("Model", typeof(TModel)) != null)
        .ToArray();
}