我对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");
}
}
我很少看到它的问题:
公共ActionResult索引(MyViewModel模型)?"
由于NyViewModel是一种复杂类型,因此您无法将其作为URL的一部分传递。你怎么称呼它?
我认为我在拼图中错过了一个大问题,而且两个问题都是相互关联的。但是,需要一些帮助才能理解这种关系
答案 0 :(得分:16)
[HttpPost]
属性告诉路由引擎将该操作方法的任何POST请求发送到另一个方法。这是一种重载。
当第一种方法不需要任何属性时,为什么第二种方法用
[HttpPost]
装饰?
方法的默认值为[HttpGet]
。因此,不需要任何属性。
是否有关于何时使用
[Http]
属性的指南,何时没有?
理想情况下,属性应该放在每个方法上,以避免混淆。随着您越来越熟悉事物的工作方式,您通常会采用快捷方式(与其他所有内容一样),并在您知道不必要时省略它们。
由于
MyViewModel
是复杂类型,因此您无法将其作为URL的一部分传递。你怎么称呼它?
数据将根据请求正文中的数据转换为模型。这可以作为JSON对象,也可以作为Form数据。 (有一些技巧可以从URL初始化对象,但它们可能有点复杂和高级。)
答案 1 :(得分:3)
通常,复杂对象在HTTP正文中传递,并使用支持它的动词,如POST和PUT。正文内容必须通过模型绑定验证。这基本上意味着如果它是带有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。
答案 2 :(得分:1)
最佳实践 - 请求处理
最佳做法是仅在控制器中使用公共方法,这些公共方法将通过视图或使用json进行维护。对于控制器中的所有公共方法,最佳做法是使用[HttpGet]
或[HttpPost]
标记它们,或者我不会涵盖的其他类型之一,因为它们是更多边缘情况。< / p>
这些Http
属性将方法限制为仅为这些特定类型的请求提供服务。虽然默认值为[HttpGet]
,但我发现在命名冲突时,在所有情况下不标记[HttpGet]
有时会导致意外行为。
最佳实践 - PRG
Post-Redirect-Get是一种设计模式,它基本上规定,无论何时您要发送来自POST请求的响应,您都应该重定向到get以发送响应。这可以防止多种情况,包括如果使用后退按钮则不会再次发布。
重定向通常以[HttpPost]
ActionResult的形式使用return RedirectToAction("MyHttpGetAction");
。
发布复杂模型
您可以通过多种方式发送复杂模型。主要区别在于,如果您使用的是GET请求,则它位于URL中,如果您使用的是POST请求,则它位于请求标头中。如果你使用ajax,那么差异会变得模糊,因为你几乎总是将它发送到身体中。