您的位置:首页 > 其它

[源码学习]调试Razor从哪里开始

2012-06-02 00:53 274 查看
使用ASP.NET MVC时,我们知道,要使用Views中的视图,需要在Action中写

 

return View();


 

这个方法返回的返回值是一个 ViewResult,进入这个类,继承了父类ViewResultBase后只写了MasterName属性和FindView方法。

不过已经开始看到到ViewEngine的踪影了。

 

protected override ViewEngineResult FindView(ControllerContext context) {
ViewEngineResult result = ViewEngineCollection.FindView(context, ViewName, MasterName);
...;
}


 


.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

跟进ViewEngineCollection.FindView去看看。

来到了ViewEngineCollection类,这是一个实现了Collection<IViewEngine>的类。

 

public virtual ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName) {
if (controllerContext == null) {
throw new ArgumentNullException("controllerContext");
}
if (string.IsNullOrEmpty(viewName)) {
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "viewName");
}

return Find(e => e.FindView(controllerContext, viewName, masterName, true),
e => e.FindView(controllerContext, viewName, masterName, false));
}


 

很简单的一个方法,跟进去

 


private ViewEngineResult Find(Func<IViewEngine, ViewEngineResult> cacheLocator, Func<IViewEngine, ViewEngineResult> locator) {
// First, look up using the cacheLocator and do not track the searched paths in non-matching view engines
// Then, look up using the normal locator and track the searched paths so that an error view engine can be returned
return Find(cacheLocator, trackSearchedPaths: false)
?? Find(locator, trackSearchedPaths: true);
}

private ViewEngineResult Find(Func<IViewEngine, ViewEngineResult> lookup, bool trackSearchedPaths) {
// Returns
//    1st result
// OR list of searched paths (if trackSearchedPaths == true)
// OR null
ViewEngineResult result;

List<string> searched = null;
if (trackSearchedPaths) {
searched = new List<string>();
}

foreach (IViewEngine engine in CombinedItems) {
if (engine != null) {
result = lookup(engine);

if (result.View != null) {
return result;
}

if (trackSearchedPaths) {
searched.AddRange(result.SearchedLocations);
}
}
}

if (trackSearchedPaths) {
// Remove duplicate search paths since multiple view engines could have potentially looked at the same path
return new ViewEngineResult(searched.Distinct().ToList());
}
else {
return null;
}
}


 


乍一看,又是for又是if、else的有点不知所措,其实仔细一看结合上面的Find参数就能找到黄色加亮的几句代码关键代码。

是遍历了注册ViewEngine集合,调用ViewEngine各自的FindView,谁能找到View,就用谁。

那么遍历的ViewEngine集合怎么来的呢?要回到ViewResult的父类ViewResultBase中去看。

 

public ViewEngineCollection ViewEngineCollection {
get {
return _viewEngineCollection ?? ViewEngines.Engines;
}
set {
_viewEngineCollection = value;
}
}


.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

如果没有定义那么就调用ViewEngines.Engines,这是一个很简单的静态类属性

 

public static class ViewEngines {

private readonly static ViewEngineCollection _engines = new ViewEngineCollection {
new WebFormViewEngine(),
new RazorViewEngine(),
};

public static ViewEngineCollection Engines {
get {
return _engines;
}
}
}


.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

回到刚才的遍历,由于RazorViewEngine的构造函数中定义了以下格式,在Views文件夹中也创建了相应的文件,所以选择了RazorViewEngine。

 

AreaViewLocationFormats = new[] {
"~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.vbhtml"
};


 

好了,终于找到了Razor。

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: