ASP.NET根据文件扩展名将HTTP请求映射到HTTP处理程序。我只是想知道它在MVC中是如何工作的,因为在MVC中我们只是指向控制器内部的action方法。我们没有指定任何扩展。
然后我尝试从 this link
了解处理程序在MVC应用程序执行过程中的工作原理但我还是不明白。任何人都可以解释处理程序在MVC中的工作方式以及它与普通ASP.NET处理程序的不同之处。
答案 0 :(得分:2)
可能你对这些术语感到困惑。
MVC使用路由表来查找到特定View的路由。
就像你有www.YourSite.com/index.aspx
一样,你有www.YourSite.com/Home/Index
。
区别在于,in ASP.Net, you will be directly loading the .aspx file
和网址in MVC, you will go to the Home controller and look for an Index action. The Index action will then render it's view
一样。
此处,每个视图或部分视图都将在控制器中包含其ActionMethod。
如果没有关联的控制器和操作,则无法呈现视图!
您可以查看this link以获取进一步的参考。
你将在Global.asax文件中有一个默认路由来完成这项工作。
如果您有任何复杂的(有多个参数),您需要手动将它们添加到路由表中。关于这一点的更多信息在链接中。
希望这会有所作为。
答案 1 :(得分:2)
事实上,这里的全面解释真的超出范围,你应该阅读它以深入学习它,如果你接受建议,如果你能找到一个,一本书通常是一个更好的资源博客帖子等(根据我的经验,博客文章可能由任何可能没有线索的人撰写)。只要确保你阅读评论,以确定一本书是否好,这样你就不会被误导。
无论如何,我会尝试概述基础知识,而不会在细节上添加太多噪音,因为这会导致太多。
正如其他人在他们的回答中已经提到的,在MVC生态系统中,有一个称为路由和路由表的概念。基本上,它们是模式的集合。请求到达时,请求标头包含请求的URL,例如:
http://localhost:12345/
http://localhost:12345/home/index
http://localhost:12345/products/catalog
http://localhost:12345/products/details/1
http://localhost:12345/promotion
有一个原因我写了不止一种,格式不同。让我们一个一个地检查它们。
http://localhost:12345/
示例
第一个,http://localhost:12345/
是最简单的,它通常被称为默认路由。通常,这指向Index
中的无参数HomeController
操作方法,默认区域(即"无区域")。请注意,动作和控制器以及区域(以及几乎任何细节)都是可配置的。您可以通过添加默认路由来完成此工作,但这通常由项目模板为您完成。您可以在App_Start / RouteConfig文件中找到它,它的name
参数为"Default"
:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
因此,每当有一个请求(其中我以原始方式说这个)的附加部分存在时,它们就会被Index
内的HomeController
动作处理。正如您在上面的代码中看到的那样,Index
和HomeController
在defaults:
参数中配置,您必须转到此处才能更改默认值。如果您改为使用名为Welcome
的操作,则需要将其传递给上述方法:
defaults: new { controller = "Home", action = "Welcome", id = UrlParameter.Optional }
另请注意,尽管我已经写过"其中没有其他部分存在",通过其他部分我只是指路段 - 例如,查询字符串?param1=value1
不会阻止选择此路线。
http://localhost:12345/home/index
示例
这与上面完全相同。我只包含了这个,所以你可以看到即使这个特定路由是默认路由,也没有什么能阻止你实际指定控制器和动作。
http://localhost:12345/products/catalog
示例
这个的基本工作方式与上面两个相同,只是这不是默认路由,因此您需要明确指定控制器和操作,以便将请求路由到适当的控制器并且行动。再看一下上面的配置代码。您可以看到已定义"{controller}/{action}/{id}"
的网址格式。您不需要来创建新路由,因为此模式可用于此示例。比较它们,你可以看到原因:
http://localhost:12345/products /catalog
{controller}/{action}/{id}
从位移可以看出,products
被识别为控制器名称,catalog
被识别为操作名称,并且id
被赋予默认值{{ 1}},可以省略它的值,路由仍然对请求有效。因此,只要默认区域中存在UrlParameter.Optional
且其中包含ProductsController
操作,其具有Catalog
参数,或者根本没有参数,或者任何现有参数一个默认值(或可以为空,在这种情况下它将被传递为null),路由系统将使用此路由作为请求。
id
示例
与上述相同,但此处http://localhost:12345/products/details/1
已映射到1
段。只要默认区域中有id
,并且其中存在ProductsController
操作,该操作根本没有参数(因为Details
是可选的,它可能是忽略),或者有一个名为id
的参数,并且如果可能存在的每个其他参数都有一个默认值(或者可以默认为null - 这意味着它是一个引用类型),那么这个路由可以用于请求。
id
示例。
这是我为特定目的而包含的特殊内容。我们假设您不拥有http://localhost:12345/promotion
。您仍然可以定义路由模式:
PromotionController
正如您所看到的,我们假设您有一个routes.MapRoute(
name: "Promo",
url: "promotion",
defaults: new { controller = "Products", action = "Promotion" }
);
,其中包含ProductsController
个动作。而您可以直接请求网址Promotion
(并且它实际上会有效)指定"专用"路线也可以。我之所以添加此示例,原因如下:
最后,让我们谈谈整个路由系统的一些事情。
可能存在将 映射到多个路由的情况。在这种情况下,定义模式的顺序是决定因素。匹配网址的第一个被选中,这意味着您应该从最具体的(也就是更少或根本没有变化的部分)开始指定您的路线模式。没有变化部分的模式的示例是我写的最后一个网址,它具有http://localhost:12345/products/promotion
的硬编码模式。您可以通过模式中没有promotion
来识别这些。最不具体的(换句话说,更一般的)应该在方法的底部。如果仍然存在重叠,则应重新考虑如何定义路线。
还有其他因素会影响是否可以选择某个操作来提供请求。例如,动作方法上{}
的存在将告诉动作调用者(以及不是路由引擎)此方法只能用于请求是POST请求(除非还应用了[HttpPostAttribute]
)。请注意,路由系统和所谓的动作调用程序是两个不同的东西 - 您可以发现自己处于这样的情况:路由系统将找到路由的模式匹配但操作调用程序找不到合适的操作 - 例如,如上所述,匹配的模式没有GET处理程序,但请求实际上是HTTP GET。这超出了您的问题范围,但希望将其作为提示包含在内,以便您了解需要查找它。上面提到的[HttpGetAttribute]
和HttpPost
属性是特殊属性,为了通过实现您自己的属性来实现此类功能,您的属性必须来自HttpGet
类。
正如您在问题中所说,请求不会映射到文件,而是映射到控制器和操作。因此,假设找到了匹配的路由模式,并且要使用的控制器恰好为ActionMethodSelectorAttribute
,并且操作为Home(Controller)
。系统做了什么(这不是路由系统从此处负责)它扫描正在运行的应用程序的程序集(使用反射)并枚举其中的所有类。它寻找符合某些标准的课程(我不确定以下内容是否100%准确和/或全面):
Index
Controller
或Home
(不确定只是HomeController
是否有效,实际上这是一个约定用名称后缀#34; Controller" )如果未找到,则根据匹配的路由无法满足请求。如果找到多个,则无法确定要使用的那个并且会引发错误。
如果找到一个匹配的类(Controller),则系统将进一步调查它。它现在将寻找以下方法:
Home
还是派生类(这不是AJAX请求所必需的)ActionResult
派生属性不会阻止根据请求属性执行操作。如果找不到或多个匹配的操作方法,则无法满足请求并引发错误。
如果只有一个匹配项,则会调用它来完成请求。
答案 2 :(得分:0)
不要太混淆
所有控制器都是类
所有行动都是方法
你只是从地址栏调用方法(函数),这些都是......
mvc处理程序检查在类(Controller)中是否存在方法(ActionRsult) 具有相同的名称和匹配的所有
的参数