ASP.NET MVC 4 视图页去哪里儿   发布时间:2017-09-11 11:00:41

ASP.NET MVC 4 视图页去哪里儿 这里特别感谢 swagon 提到了Displaymodeprovider,所以才有了本篇博客,也使我对【View的呈现】中寻找视图页的过程有了清晰的认识!

前戏

在MVC中,执行完Action之后,会返回一个ActionResult对象,之后再执行该对象的ExecuteResult方法,这也就是【View的呈现】的入口!

【View的呈现】包括了:根据模版去寻找请求的视图页、编译视图页、再执行视图页的内容。本篇就来介绍寻找视图页的详细过程,其中涉及到了MVC 4的一个新特性--“手机视图页”

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

public abstract class ViewResultBase : ActionResult

{

public override void ExecuteResult(ControllerContext context)

{

if (context == null)

{

throw new ArgumentNullException("context");

}

if (String.IsNullOrEmpty(ViewName))

{

ViewName = context.RouteData.GetRequiredString("action");

}

  ViewEngineResult result = null;

if (View == null)

{

//通过视图引擎去创建视图对象,并将视图对象和该视图相关的信息封装在ViewEngineResult对象中。

result = FindView(context);

View = result.View;

}

TextWriter writer = context.HttpContext.Response.Output;

ViewContext viewContext = new ViewContext(context, View, ViewData, TempData, writer);

View.Render(viewContext, writer);

if (result != null)

{

result.ViewEngine.ReleaseView(context, View);

}

}

}

public class ViewResult : ViewResultBase

{

protected override ViewEngineResult FindView(ControllerContext context)

{

//寻找当前请求的视图页,如果能找到则创建视图对象。

//遍历每个视图引擎(默认有两个WebFormEngine、RazorViewEngine),并执行每一个视图引擎的FindView方法。

ViewEngineResult result = ViewEngineCollection.FindView(context, ViewName, MasterName);

//如果创建了视图对象,即:指定路径中存在相匹配的视图页(.cshtml文件)。

if (result.View != null)

{

return result;

}

//没有创建视图对象,即:指定路径中不存在相匹配的视图页(.cshtml文件)。

StringBuilder locationsText = new StringBuilder();

foreach (string location in result.SearchedLocations)

{

locationsText.AppendLine();

locationsText.Append(location);

}

throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,

MvcResources.Common_ViewNotFound, ViewName, locationsText));

}

}

  ViewEngineResult result = ViewEngineCollection.FindView(context, ViewName, MasterName);则是遍历每个视图引擎(默认有两个WebFormEngine、RazorViewEngine),并执行每一个视图引擎的FindView方法。

注:在执行视图引擎的FindView方法时,先按照从缓存表中找是否存在请求的视图页,如果没有的话,再进行一次寻找!

下面以RazorViewEngine为例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

public abstract class VirtualPathProviderViewEngine : IViewEngine

{

//useCache先是true,该方法返回的是null。则让useCache=false,再执行一遍。即:先通过缓存去找,如果没有找到的话,就正经的去找。

public virtual ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)

{

if (controllerContext == null)

{

throw new ArgumentNullException("controllerContext");

}

if (String.IsNullOrEmpty(viewName))

{

throw new ArgumentException(MvcResources.Common_NullOrEmpty, "viewName");

}

string[] viewLocationsSearched;

string[] masterLocationsSearched;

string controllerName = controllerContext.RouteData.GetRequiredString("controller");

//获取视图的路径,这里就是咱们本篇博文的内容的入口点!!!!!!!!!!!!!!!!!!!

//ViewLocationFormats、AreaViewLocationFormats定义在派生类RazorViewEngine类中。

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:上海建网站 http://www.flpsz.com