Umbraco 6.1.1 SurfaceController Key Questions

I have searched for all the available tutorials that I can find, and I'm still having problems with Umbraco surface controllers. I created an example barebone surface controller that sorta works but has some problems. Here, my code still asks the following questions:

ContactformModel1.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"); } } 

Contact.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") 

My questions:

  • I am sure that return ContactFormGet(model) is erroneous in ContactFormPost, but everything I tried causes an error.

    When I try to return RedirectToCurrentUmbracoPage() , I get Cannot find the Umbraco route definition in the route values, the request must be made in the context of an Umbraco request .

    When I try to return CurrentUmbracoPage() , I get Can only use UmbracoPageResult in the context of an Http POST when using a SurfaceController form .

  • Routing works correctly (when I put a breakpoint in ContactFormPost, the debugger stops there). But when the form returns, I get the exact values ​​that I submitted. I do not see!!! attached to the email address. (Note that this bit of code is for debugging only; it is not intended to use anything useful).

  • How do I call the "SayOK" method in the controller? When I change the BeginUmbracoForm method to point to SayOK, I still loop in the ContactFormPost method.

I'm sure I'm missing something incredibly stupid, but I can't figure it out for me.

+6
source share
2 answers

I wanted to take a moment to say how I decided it. After playing a little more, I realized that in fact I am not very clear about my problem. Basically, all I'm trying to do is insert an MVC form inside the Partial View macro so that it can be used in the content of the page (not built into the template).

I could get this solution to work, but I really didn't like how much logic the author puts into the View file. So I adapted his solution this way:

Partial macro view (cshtml) file:

 @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()) } } 

Partial View File (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 file:

 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 } } 

The controller is designed in such a way that the form can be embedded either in the template or in the Partial View macro. If it is embedded in the template, the form should be placed on ubCreateComment ; if it is in a macro, send a message to CreateComment .

I am pretty sure that there is a better / more correct way to do this, but I did not have enough time to work on the project. If anyone has a better solution, submit it!

One final question / note: you will notice that partial view macros point Request.Form to ContactSurfaceController.CreateComment and MVC, magically serializing it for me. It's safe, huh? If so, is it not MVC rock? :)

+3
source

You use ChildAction because you specify @Html.Action("ContactForm", "ContactSurface") , and because of this, in your view you need to:

  • Use Html.BeginForm(...) , not 'Html.BeginUmbracoForm (...)'
  • Allow the form to post back to the same path, not to the action

If you do this, the form will return back to itself, as expected.

See here for more details.

Edit:

Just saw the final part of your question. If you intend SayOK be your thank you message, I will just call it from your HttpPost action and not return the original view.

+1
source

Source: https://habr.com/ru/post/948965/


All Articles