了解MVC中的,和Complex Actionmethod参数

我对MVC的设计模式和框架都非常陌生。 我也不是非常精通ASP.NET Forms的基础知识。 但是,我也了解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基本上是Controller / ActionMethod / Id类型,其中参数to action menthod是Primitive类型。 在上面的这个例子中,调用“需要什么样的URL”

公共ActionResult索引(MyViewModel模型)?“

由于NyViewModel是一种复杂类型,因此您无法将其作为URL的一部分传递。 你怎么称呼它?

  • 当第一种方法不需要任何属性时,为什么第二种方法用[HttpPost]装饰? 是否有关于何时使用[Http]属性的指南,何时没有?

我想我在拼图中错过了一个很大的问题,两个问题都是相互关联的。 但是,需要一些帮助才能理解这种关系

[HttpPost]属性告诉路由引擎将该操作方法的任何POST请求发送到另一个方法。 这是一种重载。

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

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

是否有关于何时使用[Http]属性的指南,何时没有?

理想情况下,属性应该放在每个方法上,以避免混淆。 随着您越来越熟悉事物的运作方式,您通常会采用快捷方式(与其他所有内容一样),并在您知道不必要时省略它们。

由于MyViewModel是一种复杂类型,因此您无法将其作为URL的一部分传递。 你怎么称呼它?

数据将根据请求正文中的数据转换为模型。 这可以作为JSON对象,也可以作为Form数据。 (有一些技巧可以从URL初始化对象,但它们可能有点复杂和先进。)

通常,复杂对象在HTTP主体中传递,并使用支持它的动词,如POST和PUT。 正文内容必须通过模型绑定validation。 这基本上意味着如果它是带有Content-Type:application / json的POST请求,它必须从JSON反序列化为MyViewModel。 如果内容是XML,则必须将其反序列化为XML。

一般约定是首先在URL路径,查询和标题中找到所有原始类型,然后在POST(或PUT)主体中找到一个复杂类型。 我相信可以在其他地方放置复杂的类型,但是你会进入类型转换器和自定义属性,如果你是初学者,你可能应该这样做。

当第一种方法不需要任何属性时,为什么第二种方法用[HttpPost]装饰? 是否有关于何时使用[Http]属性的指南,何时没有?

“[HttpPost]”告诉路由引擎此方法重载可通过HTTP POST获得。 在这种情况下,尝试使用404未找到PUT / home / index with body。 Index()的无参数版本不需要它,因为它可以使用任何HTTP动词,包括GET,POST和PUT。

最佳实践 – 请求处理

最佳做法是仅在控制器中使用公共方法,这些方法将通过视图或使用json进行维护。 对于控制器中的所有公共方法,最佳做法是使用[HttpGet][HttpPost]标记它们,或者我不会涵盖的其他类型之一,因为它们是更多边缘情况。

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

最佳实践 – PRG

Post-Redirect-Get是一种设计模式,它基本上规定,每当您要发送来自POST请求的响应时,您应该重定向到get以发送响应。 这可以防止多种情况,包括在使用后退按钮时不再发布

重定向通常以[HttpPost] ActionResult的forms使用return RedirectToAction("MyHttpGetAction");

发布复杂的模型

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