C#中控制器如何处理HTTP请求的一些澄清?

4

我完全是C#的新手,对MVC也不太了解(我来自Java)

我有以下疑问:

我有一个名为Controllers的控制器包/文件夹(我不知道在Visual Studio中的正确名称),其中包含处理传入HTTP请求的控制器。

因此,在此文件夹中,我有TestController.cs类,它大致如下:

namespace MyWebApplication.Controllers
{
    public class AndreaController : MyBaseController
    {
        // Manager che effettua la connessione ed ottiene i dati da visualizzare nella view:
        private MaliciousCodeManager manager = new MaliciousCodeManager("DefaultConnection");


        //
        // GET: /Test/

        /* Method that handle the HTTP REQUEST toward /Test/index
         * 
         */
        public ActionResult Index(DataModel.MaliciousCode.SearchMalicious model)
        {

            Debug.WriteLine("*** FILTRI DI RICERCA ***");
            ...................................................
            ...................................................
            ...................................................
            DO SOME STUFF
            ...................................................
            ...................................................
            ...................................................
        }
}

所以,我理解这个控制器处理请求指向/Test/路径的内容。

因此,Index()方法处理指向/Test/index的请求。我认为这对我来说很清楚。

现在我的疑问与传递给我的Index方法的参数有关:

public ActionResult Index(DataModel.MaliciousCode.SearchMalicious model)

所以,这个方法的输入参数是一个DataModel.MaliciousCode.SearchMalicious model对象。
当我在调试模式下执行代码时,看起来在调用Index()方法处理HTTP请求之前,它会创建一个SearchMalicious malicious对象作为参数。
所以我的疑问是:它是自动从框架中创建的吗?还是什么?我错过了什么?
谢谢 安德烈亚

1
这就是ModelBinder的作用。请参见http://msdn.microsoft.com/en-us/magazine/hh781022.aspx。 - asawyer
3个回答

2
在这种情况下,您正在指定索引所期望的类型...对象被创建,然后用户发布的值或查询字符串参数就会映射到它上面。唯一的要求是该类型必须定义一个无参构造函数,以便框架可以创建它。
在此情况下,用户无法控制所创建的类型,只能控制要映射的值。因此,理论上,如果您在构造函数中定义了恶意代码的类,并调用它,那么是开发人员的责任而不是最终用户的责任。
在模型绑定方面需要注意的是,框架不知道应该映射哪些值。因此,如果您显示一个具有用户模型类型的页面,并允许某个人更新其电子邮件,则他们可能会理论上覆盖其折扣,假设它位于同一对象上,并且他们知道属性名称。

2

是的,您的模型会被自动绑定。将参数传递给方法告诉MVC您想要模型绑定。如果您不想进行模型绑定,则传递一个空参数。如果您想控制如何执行此操作,则可以创建自定义模型绑定程序并将其添加到global.asax中的模型绑定程序列表中。

顺便说一下,您正在做出很多假设。索引不一定是默认操作,这取决于您的路由设置方式。路径/Test也不一定是使用的路径,但在默认路由条件下是正确的。


你也可以接受一个 FormCollection 参数,如果你传递了一个空参数。 - asawyer
@asawyer - 很好的观点。不过我更多地考虑了UpdateModel。 - Erik Funkenbusch

1
实际上,在请求路由中只有控制器类型名称是重要的。可能有人重命名了该类型,但忘记了重命名文件。通过查看您的代码,该Index方法将回答http://example.org/Andreahttp://example.org/Andrea/Index URL。 Index是默认路由中的默认操作名称。
如果您查看路由配置(应该在App_Start/RouteConfig.cs或Global.asax.cs中),您将看到默认路由注册。
routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

这段文字告诉ASP.NET MVC,URL的第一部分指定控制器类型,第二部分指定操作方法名称。操作方法是控制器中可以根据这些规则从URL调用的公共方法。它们的返回类型通常为ActionResult。控制器是提供操作方法的逻辑容器的类型。
ASP.NET中的模型绑定尝试从URL段、查询字符串和已发布的表单值中获取值。请注意默认路由中的最后一个段:当提供时,它告诉ASP.NET MVC从URL的第三个段创建一个名为id的路由值。因此,当我请求http://example.org/Home/Index/3时,我可以将值3绑定到我的操作方法参数值。
public class HomeController : MyBaseController
{
    public ActionResult Index(int id)
    {
        //id is 3
    }
}

在复杂的模型类型(如您的)中,绑定将查找每个属性值,就像上面那样。这里是一个例子SearchMalicious类型:
public class SearchMalicious 
{
    public string Keyword { get; set; }
    public string OrderBy { get; set; }
}

当您向http://example.org/Andrea?keyword=abc&orderby=def发出请求时,模型绑定将创建一个SearchMalicious实例,并使用查询字符串值填充这些属性。此外,该模型也可以从POST请求中的表单字段填充。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接