2012-02-02 51 views
2

我正在学习MVC 3几小时后,现在和昨晚我遇到了一个问题,看起来像解决它会很简单,但我可以'似乎找到了一个解决方案。MVC表单提交 - 重定向到无法直接从浏览器访问的操作

我有一个简单的联系表单。最终用户填写表格并提交。当他们提交表单时,我将最终用户重定向到同一控制器中的其他操作,该操作呈现“查询已提交”页面/视图,该页面/视图基本上是“感谢页面”。

控制器是这样设置的。

public ActionResult ContactUs() 
{ 
    return View(); 
} 

[HttpPost] 
public ActionResult ContactUs(ContactInfo contactInfo) 
{ 
    if (!ModelState.IsValid) 
    { 
      return View(); 
    } 

    //perform some business logic 

    return RedirectToAction("InquirySubmitted",contactInfo); 


} 

public ActionResult InquirySubmitted(ContactInfo contactInfo) 
{ 
    return View(contactInfo); 
} 

问题: 我不希望最终用户直接导航到通过浏览器的InquirySubmitted行动。
我只希望控制器中的ContactUs操作能够将用户发送到InquirySubmitted视图。

我试图使InquirySubmitted动作私人,只控制器可以调用它像这样:

private ActionResult InquirySubmitted(ContactInfo contactInfo) 

但是,这会产生一个错误,我完全可以理解,因为我迫使浏览器来请求InquirySubmitted使用RedirectToAction()。

所以我的问题很简单:什么是最好的“MVC 3风格”解决这个问题。

+1

@ Splash-X - 这是他可以做的一个选择,但如果用户由于某种原因刷新页面,它将重新提交联系请求。你通常会使用Post-Redirect-Get模式来解决这个问题。 – 2012-02-02 16:06:34

+0

@ Splash-X是的解决方案在技术上的工作表示谢意。这是一个选项。但是Mystere Man声明按下F5会导致刷新,从而再次触发我所有的业务逻辑,并且他说这个解决方案打破了PRG模式,所以我希望有一个更理想的解决方案。截至目前,我看到的唯一解决方案是下面发布的一个答案,它使用会话来查看最终用户是否来自联系页面,如果他们尝试直接访问InquirySubmitted,是否不将它们发回给它。该解决方案将与Web表单解决方案相同。 – Matt 2012-02-02 16:27:04

+0

@Matt我同意,但您的要求是,最终用户无法请求URL。通过创建一个动作,他们总是可以请求URL。 Ek0nomik是正确的,你可以使用会话变量来跟踪他们是否应该能够查看页面。您也可以查看引荐网址并查看它是否为表单页面,如果是,则显示该视图,否则返回重定向到表单。 – 2012-02-02 16:38:49

回答

2

您需要在InquirySubmitted ActionResult中放置逻辑,以防止用户在不应该查看页面的情况下查看页面。

您已经将InquirySubmitted方法传递给您的模型(ContactInfo)。你能否简单地检查传递给方法的数据,如果没有,那么将用户重定向到一个错误页面(或你选择的其他页面)?

另一种解决方案是在会话中设置一个布尔值,表示用户完成了“ContactUs”表单。然后,您可以在InquirySubmitted内检查该会话对象。

+0

是的,谢谢你的回答。是的,我可以做到这一点,这将工作。但是,我只是想知道是否有一个“MVC 3特定功能”,我不知道可以处理这个问题,而不必在会话中插入跟踪数据。 – Matt 2012-02-02 16:05:37

+0

@Matt - 你需要这个安全吗?我对检查'ContactInfo'模型的其他建议也有效。但是,这种模式真的只是简单的GET参数,所以这些可能是伪造的。 – 2012-02-02 16:47:09

+0

该解决方案与您在网络表单应用中使用的解决方案相同,但似乎仍然是最好的解决方案。有效和简单。公共ActionResult InquirySubmitted(ContactInfo contactInfo) { if(Session [“ContactFormSubmitted”] ==“true”) { Session [“ContactFormSubmitted”] =“false”; return View(contactInfo); } else return RedirectToAction(“ContactUs”); } – Matt 2012-02-02 16:48:05

2

首先,我不得不说。谁在乎,如果有人可以直接导航到查询提交页面?有没有机密信息,或者有什么敏感的东西?如果不是,那又如何?它受伤了什么?

但是,如果你决定这样做。 “如何使某个操作无法直接从浏览器访问”的问题的答案是您可以简单地使用Html.Action()来呈现页面,然后使用[ChildActionOnly]属性修饰操作方法。

尽管这实际上并未解决问题,因为使间接访问的操作只能回答您的问题,而不能解决您的问题。最终,您需要将用户重定向到一个url来加载页面,因此您需要一些逻辑来确定他们是否可以查看该页面。这是

0

不知道这是否仍然适用于MVC3,但在MVC2它的工作。

您的global.asax文件中包含您的网址结构。您可以将您的InquirySubmitted添加到那里无法访问的网址列表。

相关问题