6

我搜索了所有我能找到的可用教程,但我仍然无法使用 Umbraco Surface 控制器。我创建了一个基本的 Surface Controller 示例,该示例可以正常工作,但存在一些问题。到目前为止,这是我的代码,需要遵循的问题:

联系formModel1.cs:

public class ContactFormModel1
{

    public string Email { get; set; }
    public string Name { get; set; }
    public string HoneyPot { get; set; }

    public string Title { get; set; }
    public string Last { get; set; }
    public string First { get; set; }
    public string Addr { get; set; }
    public string Phone { get; set; }
    public string Time { get; set; }
    public string Comment { get; set; }
}

ContactSurfaceController.cs:

public class ContactSurfaceController : Umbraco.Web.Mvc.SurfaceController
{

    public ActionResult Index()
    {
        return Content("this is some test content...");
    }

    [HttpGet]
    [ActionName("ContactForm")]
    public ActionResult ContactFormGet(ContactFormModel1 model)
    {
        return PartialView("~/Views/ContactSurface/Contact1.cshtml", model);
    }

    [HttpPost]
    [ActionName("ContactForm")]
    public ActionResult ContactFormPost(ContactFormModel1 model)
    {
        // Return the form, just append some exclamation points to the email address
        model.Email += "!!!!";
        return ContactFormGet(model);
    }


    public ActionResult SayOK(ContactFormModel1 model)
    {
        return Content("OK");
    }

}

联系人.cshtml:

@model ContactFormModel1

 @using (Html.BeginUmbracoForm<ContactSurfaceController>("ContactForm"))
 {
     @Html.EditorFor(x => Model)
     <input type="submit" />
 }

ContactMacroPartial.cshtml:

@inherits Umbraco.Web.Macros.PartialViewMacroPage

@Html.Action("ContactForm", "ContactSurface")

我的问题:

  1. 我很确定这return ContactFormGet(model)在 ContactFormPost 方法中是错误的,但是我尝试过的所有其他方法都会引发错误。

    当我尝试return RedirectToCurrentUmbracoPage()时,我得到了Cannot find the Umbraco route definition in the route values, the request must be made in the context of an Umbraco request

    当我尝试return CurrentUmbracoPage()时,我得到了Can only use UmbracoPageResult in the context of an Http POST when using a SurfaceController form

  2. 路由似乎工作正常(当我在 ContactFormPost 中放置一个断点时,调试器停在那里)。但是当表单返回时,我得到了我提交的确切值。我没看到!!!附加到电子邮件地址。(注意,这段代码仅用于调试,并不意味着做任何有用的事情)。

  3. 如何在控制器中调用“SayOK”方法?当我将 BeginUmbracoForm 方法更改为指向 SayOK 时,我仍然卡在 ContactFormPost 方法中。

我确定我错过了一些非常愚蠢的东西,但我无法终生解决这个问题。

4

2 回答 2

3

我想花点时间谈谈我是如何解决这个问题的。在玩了一些之后,我意识到我并没有真正清楚地说明我的问题。基本上,我要做的就是在部分视图宏中嵌入一个 MVC 表单,以便可以在页面内容中使用它(而不是嵌入在模板中)。

我可以让这个解决方案发挥作用,但我真的不喜欢作者在视图文件中放入了多少逻辑。所以我以这种方式调整了他的解决方案:

部分视图宏 (cshtml) 文件:

@inherits Umbraco.Web.Macros.PartialViewMacroPage
@using Intrepiware.Models
@{
    bool isPostback = !String.IsNullOrEmpty(Request.Form["submit-button"]);
    if(isPostback)
    {
        @Html.Action("CreateComment", "ContactSurface", Request.Form)   
    }
    else
    {
        @Html.Partial("~/Views/Partials/ContactForm.cshtml", new ContactFormModel())
    }

}

表单部分视图 (cshtml) 文件:

@using Intrepiware.Models
@using Intrepiware.Controllers
@model ContactFormModel

<p>
    <span style="color: red;">@TempData["Errors"]</span>
</p>
<p>
    @TempData["Success"]
</p>
<div id="cp_contact_form">

@using(Html.BeginUmbracoForm("CreateComment", "BlogPostSurface"))
{
    @* Form code goes here *@
}

ContactSurfaceController.cs 文件:

public class ContactSurfaceController : Umbraco.Web.Mvc.SurfaceController
{
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult ubCreateComment(ContactFormModel model)
    {
        if (processComment(model) == false)
            return CurrentUmbracoPage();
        else
            return RedirectToCurrentUmbracoPage();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult CreateComment(ContactFormModel model)
    {
        if(processComment(model) == true)
        {
            TempData["Success"] = "Thank you for your interest. We will be in contact with you shortly.";
            ModelState.Clear();
        }
        return PartialView("~/Views/Partials/ContactForm.cshtml");
    }

    private bool processComment(ContactFormModel model)
    {
            // Handle the model validation and processing; return true if success
    }

}

控制器的设计使得表单可以嵌入到模板或部分视图宏中。如果它嵌入在模板中,则表单应发布到ubCreateComment; 如果它在宏中,请发布到CreateComment.

我几乎肯定有一种更好/更正确的方法可以做到这一点,但我没时间去做这个项目。如果有人有更好的解决方案,请发布!

最后一个问题/注意:您会注意到部分视图宏将 Request.Form 发布到 ContactSurfaceController.CreateComment,并且 MVC 神奇地为我序列化了它。这很安全,是吗?如果是这样,MVC 不摇滚吗?:)

于 2013-07-17T05:27:13.117 回答
1

您正在使用 ChildAction 是因为您正在指定@Html.Action("ContactForm", "ContactSurface"),因此,在您的视图中,您需要:

  • 使用Html.BeginForm(...)而不是'Html.BeginUmbracoForm(...)'
  • 允许表单回发到同一路径而不是操作

如果您这样做,则表单将按预期回发给自身。

请参阅此处的文档以获取更多帮助。

编辑:

刚刚看到你问题的最后一部分。如果您打算SayOK成为您的“谢谢”信息,我只会从您的HttpPost操作中调用它,而不是返回初始视图。

于 2013-07-09T12:18:14.823 回答