Yes this will work with 4.10 -> 7.1.1. Its probably a good point you have made that documentation relevancy to version is not really very well indicated and it would be good if all relevant versions were tagged not just a vague start point.
Indeed. All I've been trying to do for the last 6 hours or more is to generate a form to send an email. Have just about got the form to render. Now need to find out how to get the data off it and then find out how to send an email. Can't use Contour because you can't apply styles and data attributes to form elements. So many false starts, costing a fortune. This would have been a half hour job back in the day! Sorry if I sound frustrated, but it seems to be par for the course with Umbraco.
Its made up of 3 parts, Model, a View and the Controller.
In the Models folder create your model class file to represent your form data and call it something like ContactModel.cs it should look something like this. (Im using an Extension library to help validate the form data DataAnnotationsExtensions is available via nuget)
using System.ComponentModel.DataAnnotations;
using DataAnnotationsExtensions;
namespace Website.Models
{
public class ContactModel
{
[Required]
public string Name { get; set; }
[Required, Email]
public string Email { get; set; }
[Required]
public string Message { get; set; }
}
}
You need a controller to handle the requests and process the form. In umbraco this is a special type of controller called a Surface controller. It's just like a standard Umbraco Controller but it knows about Umbraco and has access to Umbraco information and helpers. It could look like this. This file lives in the Controllers folder and in my case I called it ContactSurfaceController.cs
using System;
using System.Web.Mvc;
using Umbraco.Core.Models;
using Umbraco.Web;
using Umbraco.Web.Mvc;
using Webster.Web.Helpers;
using Webster.Web.Models.Forms;
namespace Website.Controllers
{
public class ContactSurfaceController : SurfaceController
{
public ActionResult RenderContactForm()
{
return PartialView("/Views/Partials/ContactForm.cshtml", new ContactModel{});
}
public ActionResult HandleContactForm(ContactModel model)
{
if (!ModelState.IsValid)
{
return CurrentUmbracoPage();
}
var msgBody = "<html><body><p>" + model.Message + "</p><p>From:" + model.Name + ", Email:" + model.Email + "</p></body></html>";
//the very simple email sender in Umbraco
library.SendMail("[email protected]","[email protected]","Email from website",msgBody,true);
TempData.Add("sent", true);
return CurrentUmbracoPage();
}
}
}
And the form view which is the form markup. This goes in the Views folder and usually in the partials folder. My view is called ContactForm.cshtml.
@using Website.Controllers
@model Website.Models.ContactModel
@* the following line creates the correct form tag required to post the form back to the handleContactForm action on the controller *@
@using (Html.BeginUmbracoForm<ContactSurfaceController>("handleContactForm"))
{
<div>
<div class="form-row">
@Html.LabelFor(x => x.Name, "Your Name*")
@Html.TextBoxFor(x => x.Name)
@Html.ValidationMessageFor(x=>x.Name)
</div>
<div class="form-row">
@Html.LabelFor(x => x.Email, "Your Email*")
@Html.TextBoxFor(x => x.Email)
@Html.ValidationMessageFor(x => x.Email)
</div>
<div class="form-row">
@Html.LabelFor(x => x.Message, "Your Message*")
@Html.TextAreaFor(x => x.Message)
@Html.ValidationMessageFor(x => x.Message)
</div>
<div class="button-row">
<input type="submit" name="submit" value="send message">
</div>
}
Last step is to actually render the form on one of your templates / views.
In the view that you want toe form to appear call the action on the controller that renders the form view with the correct model.
Make sure to notice that when we call the controller you don't need to include the name Controller as MVC knows how to handle this and appends it automatically in the background.
Anyway the above is about the minimum required in Umbraco to send a simple contact form in Umbraco without using contour. Its mostly off the top of my head so hopefully there are not too many mistakes. I hope it helps. :)
Over the last 6 (now 8) hours solid on a beautiful Sunday, I've kind of cobbled together most of it but still can't send an email with a return that tells me if it's gone or not. My code it looks much more complex than yours, probably unnecessarily, but that's what happens in these situations. Unfortunately the Umbraco.Library.SendMail doesn't give a return so you can't do the "If mail is sent do X otherwise do Y". So I'm slogging on I'm afraid with System.Net.Mail SmtpClient etc :(
Yes you are right the library.SendMail fails silently in the background which is not super helpful. You might want to change the helper method out for standard .net smtp send mail.
try{
using (var client = new SmtpClient())
{
var mail = new MailMessage(fromAddress, toAddress);
mail.Subject = subject;
mail.IsBodyHtml = true;
mail.Body = emailBody;
client.Send(mail);
}
}catch(Exception ex){
//do something when it fails
}
Also make sure that your SMTP configuration in the web.config is setup right too.
One last thing. I did all this and got it working in a seperate project and copied the dll to the umbraco install. I've just tried to bring it into the site itself rather than have in a seperate project. Changed the namespace in the files to my website project name and umbraco wouldn't recognise it at run time. Is there something you have to do to register a namespace? Do you have to "build" umbraco if you add controllers etc?
Documentation currency for MVC form building
Is http://our.umbraco.org/documentation/Reference/Mvc/forms/turorial-partial-views still current for a V6.1.5 MVC site? It says it's good for V4.10.0+.
Please advise as trying to get out of date (or wrong versioned) demo code going is a huge waste of time (cost) to me when developing Umbraco sites.
Thanks
Craig
Hi Craig
Yes this will work with 4.10 -> 7.1.1. Its probably a good point you have made that documentation relevancy to version is not really very well indicated and it would be good if all relevant versions were tagged not just a vague start point.
Peter
Indeed. All I've been trying to do for the last 6 hours or more is to generate a form to send an email. Have just about got the form to render. Now need to find out how to get the data off it and then find out how to send an email. Can't use Contour because you can't apply styles and data attributes to form elements. So many false starts, costing a fortune. This would have been a half hour job back in the day! Sorry if I sound frustrated, but it seems to be par for the course with Umbraco.
Hi Craig
Hers a quick run down of how to go about it.
Its made up of 3 parts, Model, a View and the Controller.
In the Models folder create your model class file to represent your form data and call it something like ContactModel.cs it should look something like this. (Im using an Extension library to help validate the form data DataAnnotationsExtensions is available via nuget)
You need a controller to handle the requests and process the form. In umbraco this is a special type of controller called a Surface controller. It's just like a standard Umbraco Controller but it knows about Umbraco and has access to Umbraco information and helpers. It could look like this. This file lives in the Controllers folder and in my case I called it ContactSurfaceController.cs
And the form view which is the form markup. This goes in the Views folder and usually in the partials folder. My view is called ContactForm.cshtml.
Last step is to actually render the form on one of your templates / views.
In the view that you want toe form to appear call the action on the controller that renders the form view with the correct model.
Make sure to notice that when we call the controller you don't need to include the name Controller as MVC knows how to handle this and appends it automatically in the background.
Anyway the above is about the minimum required in Umbraco to send a simple contact form in Umbraco without using contour. Its mostly off the top of my head so hopefully there are not too many mistakes. I hope it helps. :)
Peter
Thanks Peter,
Over the last 6 (now 8) hours solid on a beautiful Sunday, I've kind of cobbled together most of it but still can't send an email with a return that tells me if it's gone or not. My code it looks much more complex than yours, probably unnecessarily, but that's what happens in these situations. Unfortunately the Umbraco.Library.SendMail doesn't give a return so you can't do the "If mail is sent do X otherwise do Y". So I'm slogging on I'm afraid with System.Net.Mail SmtpClient etc :(
Thanks,
Craig
Yes you are right the library.SendMail fails silently in the background which is not super helpful. You might want to change the helper method out for standard .net smtp send mail.
Also make sure that your SMTP configuration in the web.config is setup right too.
Whoopeee! I have mail!!! That last bit just saved me from throwing myself off the 10th floor balcony.
I'll now look at "regularising" my code with yours to make it a bit clearer.
Thank you so much :)
Craig
No worries glad that I saved you from code suicide!
Make sure to make the answer. It helps others know that its closed off and that you found the solution :)
Peter
One last thing. I did all this and got it working in a seperate project and copied the dll to the umbraco install. I've just tried to bring it into the site itself rather than have in a seperate project. Changed the namespace in the files to my website project name and umbraco wouldn't recognise it at run time. Is there something you have to do to register a namespace? Do you have to "build" umbraco if you add controllers etc?
Craig
is working on a reply...