Asp.net-Mvc
Sitecore MVC - 如何處理頁面上的多個表單
我一直在研究 Sitecore MVC,但我不知道如何處理我的頁面有兩個控制器渲染並且每個都包含一個表單的情況。我希望各個控制器處理他們的 HttpPost 並在發布後返回整個頁面。
我已經建立了一個簡單的例子。兩個控制器都相似:
public class ExampleController : Sitecore.Mvc.Controllers.SitecoreController { public override ActionResult Index() { return View("Index"); } [HttpPost] public ActionResult Index(string formPostData) { ViewBag.SaveForLater = formPostData; return Index(); } }視圖如下所示:
@using Sitecore.Mvc @using (Html.BeginRouteForm(Sitecore.Mvc.Configuration.MvcSettings.SitecoreRouteName, FormMethod.Post)) { @Html.AntiForgeryToken() var term = ViewBag.SaveForLater as string; if (!string.IsNullOrEmpty(term)) { <p>Submitted: @term</p> } <p> @Html.Sitecore().FormHandler("Example", "Index") <input type="text" name="formPostData" placeholder="Enter something" /> <input type="submit" name="submit" value="Search" /> </p> }通過此設置,兩個表單都送出了它們的數據,但返回的頁面僅包含部分視圖而不是整個頁面。
如果我替換該行
@Html.Sitecore().FormHandler("Example", "Index"),@Html.Sitecore().FormHandler()則返回整個頁面,但處理兩種表單的發布操作。這兩種情況都不理想。我一定錯過了一些東西,並希望得到一個指針。
不幸的是,您可以通過多種方式與 Sitecore MVC 集成,而 Sitecore 並沒有提供很多最佳實踐範例。您可以在此處找到一個範例。
在我們的項目中,我們這樣做有點不同,因為我們希望盡可能多地使用預設 ASP.NET MVC 中的約定等。我嘗試在這篇文章中包含一個完整的簡單範例。
我們使用目前操作和目前控制器向表單添加兩個不同的隱藏欄位,視圖如下所示:
@model Website.Models.TestViewModel @using (Html.BeginForm()) { @Html.LabelFor(model => model.Text) @Html.TextBoxFor(model => model.Text) <input type="submit" value="submit" /> <input type="hidden" name="fhController" value="TestController" /> <input type="hidden" name="fhAction" value="Index" /> }使用這個簡單的 ViewModel:
namespace Website.Models { public class TestViewModel { public string Text { get; set; } } }然後我們創建了一個自定義屬性來檢查目前控制器/動作是否與發布的相同:
public class ValidateFormHandler : ActionMethodSelectorAttribute { public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) { var controller = controllerContext.HttpContext.Request.Form["fhController"]; var action = controllerContext.HttpContext.Request.Form["fhAction"]; return !string.IsNullOrWhiteSpace(controller) && !string.IsNullOrWhiteSpace(action) && controller == controllerContext.Controller.GetType().Name && methodInfo.Name == action; } }然後控制器操作獲取新屬性:
namespace Website.Controllers { public class TestController : Controller { public ActionResult Index() { return View(); } [HttpPost] [ValidateFormHandler] public ActionResult Index(TestViewModel model) { return View(model); } } }我們總是返回由 ASP.NET MVC 解析的視圖。按照慣例,這是與文件夾中與控制器同名的操作同名的視圖。
這種方法對我們非常有效。如果您想添加
AntiForgeryToken,這也可以正常工作。