Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 理解MVC中的[HttpPost]、[HttpGet]和复杂Actionmethod参数_C#_Asp.net_Asp.net Mvc_Asp.net Mvc 4 - Fatal编程技术网

C# 理解MVC中的[HttpPost]、[HttpGet]和复杂Actionmethod参数

C# 理解MVC中的[HttpPost]、[HttpGet]和复杂Actionmethod参数,c#,asp.net,asp.net-mvc,asp.net-mvc-4,C#,Asp.net,Asp.net Mvc,Asp.net Mvc 4,我对MVC的设计模式和框架非常陌生。我也不是非常精通ASP.NET表单的基础知识。不过,我确实了解web开发和HTTP Post和GET的基础知识 现在,我已经学习了一些MVC教程,我想我已经很好地掌握了MVC模式的工作原理以及“路由引擎”的工作原理。然后我突然发现了一个代码,看起来如下: public class HomeController : Controller { public ActionResult Index() { return View(new

我对MVC的设计模式和框架非常陌生。我也不是非常精通ASP.NET表单的基础知识。不过,我确实了解web开发和HTTP Post和GET的基础知识

现在,我已经学习了一些MVC教程,我想我已经很好地掌握了MVC模式的工作原理以及“路由引擎”的工作原理。然后我突然发现了一个代码,看起来如下:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel());
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return Content("Thanks", "text/html");
    }
}
我对它有几个问题:

  • 我对路由引擎的理解是,控件被传递给基于URL的特定的ActionMethod,通常URL基本上是控制器/ActionMethod/Id类型,其中ActionMethod的参数是相当原始的类型。在上面的示例中,需要什么样的URL才能调用“
公共行动结果索引(MyViewModel模型)?”

由于NyViewModel是一个复杂类型,所以不能将其作为URL的一部分传递。你怎么能叫它

  • 当第一个方法不需要任何属性时,为什么第二个方法用[HttpPost]修饰?关于何时使用[Http]属性以及何时不使用[Http]属性,是否有任何指导原则
我想我在这个谜题中漏掉了一个大图,这两个问题是相互关联的。但是,在处理关系方面需要一些帮助

最佳实践-请求处理

最好的做法是只在控制器中使用公共方法,这些方法将通过视图或json提供服务。对于控制器中的所有公共方法,最佳做法是使用
[HttpGet]
[HttpPost]
标记它们,或者使用我不介绍的其他类型之一标记它们,因为它们是更边缘的情况

这些
Http
属性将方法限制为仅服务于那些特定类型的请求。虽然默认值是
[HttpGet]
,但我发现在所有场景中不标记
[HttpGet]
有时会导致命名冲突时出现意外行为

最佳实践-PRG

Post Redirect Get是一种设计模式,它本质上规定,在任何时候发送来自Post请求的响应时,都应该重定向到Get以发送响应。这可以防止出现许多情况,包括如果使用“后退”按钮,则不会再次发布

重定向通常以
[HttpPost]
操作结果的形式出现,使用
返回重定向到操作(“MyHttpGetAction”)

发布复杂模型


可以通过多种方式发送复杂模型。主要区别在于,如果使用GET请求,它位于url中,如果使用POST请求,它位于请求头中。如果您使用ajax,那么差异就会变得模糊,因为您几乎总是将其发送到主体中。

属性告诉路由引擎将任何POST请求发送到该操作方法,然后再发送到另一个方法。这是一种重载

当第一个方法不需要任何属性时,为什么第二个方法用
[HttpPost]
修饰

方法的默认值是
[HttpGet]
。因此,不需要属性

关于何时使用
[Http]
属性以及何时不使用,是否有任何指导原则

理想情况下,每个方法上都应该有属性,以避免混淆。当你越来越熟悉事物的运作方式时,你通常会选择捷径(就像其他事情一样),当你知道它们不是必需的时候,就忽略它们

因为
MyViewModel
是一个复杂类型,所以不能将其作为URL的一部分传递。你怎么能叫它


数据将从请求主体中的数据转换为模型。这可以是JSON对象,也可以是表单数据。(从URL初始化对象有一些技巧,但它们可能有点复杂和高级。)

通常,复杂对象通过支持它的动词(如POST和PUT)在HTTP正文中传递。正文内容必须通过模型绑定验证。这基本上意味着,如果它是一个内容类型为application/json的POST请求,它必须从json反序列化到MyViewModel中。如果内容是XML,则必须将其反序列化为XML

一般的约定是,首先在URL路径、查询和标题中找到所有基本类型,然后从POST(或PUT)正文中找到一个复杂类型。我相信把复杂类型放在别处是可能的,但是如果你是一个初学者,那么你可能会进入类型转换器和自定义属性

当第一个方法不需要任何属性时,为什么第二个方法用[HttpPost]修饰?关于何时使用[Http]属性以及何时不使用[Http]属性,是否有任何指导原则


“[HttpPost]”正在告诉路由引擎此方法重载仅通过HTTP POST可用。在这种情况下,尝试将/home/index与一个body放在一起将失败,因为找不到404。Index()的无参数版本不需要它,因为它可以处理任何HTTP谓词,包括GET、POST和PUT。

我喜欢这个答案,因为它直接回答了问题,还纠正了复杂对象不能通过URL传入的错误观念。NET的模型绑定非常健壮!这里有一个很好的例子来说明为什么@krillgar说它会变得复杂(即奇怪!)这是一个很好的解释。但是,如果我们不在上面的代码中使用[HttpPost],那也没关系吗?@AntiMafia我不知道你的意思
[HttpGet]
是唯一可选的方法,因为GET是默认的HTTP方法。任何时候你想写一篇文章,你都需要用属性来修饰这个动作。@krillgar基于上面的代码,如果我不使用[HttpPost]怎么办?好吗?你能给runni编程吗