【问题标题】:In Umbraco 6.1.1 MVC 4, how can I do a form post back to a surface controller using a model that inherits from Umbraco's RenderModel?在 Umbraco 6.1.1 MVC 4 中,如何使用从 Umbraco 的 RenderModel 继承的模型将表单回发到表面控制器?
【发布时间】:2013-06-22 00:36:51
【问题描述】:

情景:

我正在使用 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. 当我将模型显式添加到表单的路由值时 帖子,为什么它通过为空?

感觉必须有一个简单的解决方案,我可能错过了一些基本的东西。搜索论坛有很多劫持路由和继承自 RenderModel 的示例,以及使用自定义模型和表面控制器来处理表单帖子,但当自定义模型从 RenderModel 继承时,不是这两个组合。

如果我找不到解决方案,我将不得不求助于不从 RenderModel 继承,因此不允许在联系我们表单中包含任何可编辑的内容,这似乎破坏了 Umbraco 的对象。或者,创建另一个模型纯粹用于不从 RenderModel 继承但复制我的 ContactFormModel 中的所有字段的表面控制器,这简直太疯狂了!

感谢您的任何想法或建议。

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-4 umbraco


    【解决方案1】:

    好的,我没有对这个问题做出任何回应,但现在我可以自己回答了。也许这是一个根本性的疏忽,但不是那么明显,而且 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 会填充所有输入的详细信息。

    【讨论】:

    • 感谢您提供信息 - Umbraco 文档在这里应该会更好,使用自定义模型发回是绝对基础。
    • 很遗憾,这是因为整个 Umbraco 都在进行中。这是几乎所有开源项目都进行的公平交换。一种“如果您向我们展示您的,我们将向您展示我们的”交易,您可以免费获得一些东西,但必须用自己的汗水支付。我知道这可能会让人抓狂,但这是任何前沿事物的本质。如果您不想冒这种风险,请考虑使用旧版本,因为 MVC 实现正在进行中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    相关资源
    最近更新 更多