Asp.net-Mvc

在 Umbraco 6.1.1 MVC 4 中,如何使用從 Umbraco 的 RenderModel 繼承的模型將表單回發到表面控制器?

  • December 13, 2016

場景:

我正在使用 MVC 在 Umbraco 6 中建構一個站點 - 我對 Umbraco 還很陌生,但到目前為止我已經按照教程等完成了所有工作,並且在大多數情況下一切都很好。

所以我有一個建構為部分視圖的“聯繫我們”表單,使用以下程式碼呈現:

@using (Html.BeginUmbracoForm("SendEmail", "ContactFormSurface"))
{

發回我的 ContactFormSurfaceController:

public class ContactFormSurfaceController : Umbraco.Web.Mvc.SurfaceController
{
   [HttpPost]
   public ActionResult SendEmail(ContactFormModel model)
   {

現在,我的 ContactFormModel 繼承自 Umbraco RenderModel,我在單獨的 ContactFormController 中“劫持”了我的 Contact Us 視圖的路由:

public class ContactFormController : RenderMvcController
{
   //
   // GET: /Contact-us/

   public override ActionResult Index(RenderModel model)
   {
       var contactFormModel = new ContactFormModel(model);
       return CurrentTemplate(contactFormModel);
   }

我想要這個,以便我可以在基於 Umbraco 內容的聯繫表單中擁有靈活的標題和送出按鈕文本。我的 ContactFormModel 在它的建構子中使用了一個 RenderModel,以便它可以訪問底層的 Umbraco 內容:

public class ContactFormModel : RenderModel
{
   #region Ctr

   public ContactFormModel(RenderModel model) : base(model.Content, model.CurrentCulture) {}

   #endregion


   #region Contact Form Fields

   [Display(Name = "Your Name")]
   [Required]
   public string Name { get; set; }

問題:

當表單回傳到我的表面控制器 SendEmail 方法時,似乎試圖實例化一個新的 ContactFormModel,我得到一個 YSOD,但有以下異常:

沒有為此對象定義無參數建構子。

我的第一個想法是,好吧,我將提供一個無參數建構子,因為我實際上不需要訪問 SendEmail 表面控制器方法中的 Umbraco 內容,我只希望在最初渲染視圖時這樣做。但這並不容易,因為基礎 RenderModel 需要將 IPublishedContent 對像傳遞給它的建構子。我嘗試只傳遞null,並且:

public ContactFormModel() :base(new DynamicPublishedContent(null)) {}

但這會導致“值不能為空”異常。

然後我嘗試將我的 Umbraco 表單聲明更改為:

@using (Html.BeginUmbracoForm("SendEmail", "ContactFormSurface", new {model = @Model}))

以確保將傳遞給視圖的 ContactFormModel 發送回表面控制器。這通過了 YSOD,但在表面控制器 SendEmail 方法中,“模型”為空。

所以有幾件事我不太明白:

  1. 為什麼首先嘗試在我的 ContactFormModel 上呼叫無參數建構子?為什麼視圖中的 ContactFormModel 不僅僅在表面控制器方法中可用,因為這是我指定的?
  2. 當我將模型顯式添加到表單文章的路由值時,為什麼它會以 null 出現?

感覺必須有一個簡單的解決方案,我可能錯過了一些基本的東西。搜尋論壇有很多劫持路由和繼承自 RenderModel 的範例,並且當自定義模型繼承自 RenderModel 時,還使用自定義模型和表面控制器來處理表單文章,但不是這兩個組合。

如果我找不到解決方案,我將不得不求助於不從 RenderModel 繼承,因此不允許在聯繫我們表單中包含任何可編輯的內容,這似乎破壞了 Umbraco 的對象。或者,創建另一個模型純粹用於不從 RenderModel 繼承但複製我的 ContactFormModel 中的所有欄位的表面控制器,這簡直太瘋狂了!

感謝您的任何想法或建議。

好的,我對這個問題沒有任何回應,但現在我可以自己回答了。也許這是一個根本性的疏忽,但不是那麼明顯的恕我直言,Umbraco 論壇等關於從 RenderModel 繼承的資訊相當有限。

本質上,正如我的第一直覺,答案是通過提供無參數建構子來解決原始異常“沒有為此對象定義無參數建構子”。困難在於為我的模型確定在無參數建構子中放入什麼,因為它繼承自 Umbraco RenderModel,它需要將 IPublishedContent 實例傳遞給它的建構子。

幸運的是,在瀏覽 Umbraco 論壇時,我偶然發現了這篇文章:http: //our.umbraco.org/forum/developers/api-questions/40754-Getting-CurrentPage-from-SurfaceController

我沒有完全理解的是目前頁面/視圖資訊是如何通過 Umbraco Context 傳遞的。所以根據上面的文章,我為我的自定義模型創建了幾個新的建構子:

   public ContactFormModel() : this(new UmbracoHelper(UmbracoContext.Current).TypedContent(UmbracoContext.Current.PageId)) {}
   public ContactFormModel(IPublishedContent content) : base(content) {}

有了這些,當我現在將表單發布回我的 Surface Controller 方法時,就像變魔術一樣,我的 ContactFormModel 會填充所有輸入的詳細資訊。

引用自:https://stackoverflow.com/questions/17293530