Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • apload-gmbh 39 posts 109 karma points
    Jun 07, 2023 @ 13:54
    apload-gmbh
    0

    Contact Form via Controller

    Hello community

    I'm trying to create a contact form in Umbraco 9 CMS. I tried several solutions, wich all didn't work out. My last attempt was to make a view-file (Kontaktformular.cshtml), a controller (FormController.cs) and an integration in Startup.cs. When i send the form it sais: Could not find a Surface controller route in the RouteTable for controller name FormController. Now am at the point, where I don't know, what else I should do, to make that form work.

    It would be great, if anybody could help me with that. You can see me code below.

    Thank you!

    Startup.cs:

    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Routing;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using Microsoft.Extensions.Logging;
    using Serilog;
    using Serilog.Context;
    using System;
    using System.Configuration;
    using System.Diagnostics;
    using Umbraco.Cms.Core.DependencyInjection;
    using Umbraco.Cms.Web.BackOffice.Controllers;
    using Umbraco.Extensions;
    using Microsoft.AspNetCore.Mvc;
    using Umbraco.Cms.Web;
    using Umbraco.Cms.Web.Common.Controllers;
    
    
    namespace Umbraco9.Web
    {
        public class Startup
        {
            private readonly IWebHostEnvironment _env;
            private readonly IConfiguration _config;
    
            /// <summary>
            /// Initializes a new instance of the <see cref="Startup" /> class.
            /// </summary>
            /// <param name="webHostEnvironment">The web hosting environment.</param>
            /// <param name="config">The configuration.</param>
            /// <remarks>
            /// Only a few services are possible to be injected here https://github.com/dotnet/aspnetcore/issues/9337
            /// </remarks>
            public Startup(IWebHostEnvironment webHostEnvironment, IConfiguration config)
            {
                _env = webHostEnvironment ?? throw new ArgumentNullException(nameof(webHostEnvironment));
                _config = config ?? throw new ArgumentNullException(nameof(config));
            }
    
            /// <summary>
            /// Configures the services.
            /// </summary>
            /// <param name="services">The services.</param>
            /// <remarks>
            /// This method gets called by the runtime. Use this method to add services to the container.
            /// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
            /// </remarks>
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddUmbraco(_env, _config)
                    .AddBackOffice()
                    .AddWebsite()
                    .AddComposers()
                    .Build();
    
                services.AddRouting();
            }
    
            /// <summary>
            /// Configures the application.
            /// </summary>
            /// <param name="app">The application builder.</param>
            /// <param name="env">The web hosting environment.</param>
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {   
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    app.UseExceptionHandler("/Error");
                    app.UseHsts();
                }
    
                app.UseStatusCodePages();
    
                app.UseUmbraco()
                    .WithMiddleware(u =>
                    {
                        u.UseBackOffice();
                        u.UseWebsite();
                    })
                    .WithEndpoints(u =>
                    {
                        u.UseInstallerEndpoints();
                        u.UseBackOfficeEndpoints();
                        u.UseWebsiteEndpoints();
                    });
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllerRoute(
                        name: "FormController",
                        pattern: "Form/{action}",
                        defaults: new { controller = "FormController", action = "Index" }
                    );
    
                    endpoints.MapControllers();
                });
    
            }
        }
    }
    

    Kontaktformular.cshtml:

    @using Umbraco.Cms.Core.Models
    @using Umbraco.Cms.Web.Common.PublishedModels;
    @using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
    @using Microsoft.AspNetCore.Mvc;
    @using Umbraco.Cms.Core.Models.PublishedContent;
    @using Umbraco.Cms.Web.Common.Controllers;
    
    
    @{
        Layout = "Master.cshtml";
    }
    
    <section class="formulate">
        <div class="container">
            @using (Html.BeginUmbracoForm("SubmitForm", "FormController", FormMethod.Post))
            {
                @Html.AntiForgeryToken()
                <fieldset>
                    <div class="form-group">
                        <label for="firstName">Vorname</label>
                        <input
                            type="text"
                            name="firstName"
                            class="form-control"
                            placeholder="Vorname eingeben"
                            value=""
                            required 
                        />
                    </div>
                    <div class="form-group">
                        <label for="lastName">Nachname</label>
                        <input
                            type="text"
                           name="lastName"
                            class="form-control"
                            placeholder="Nachname eingeben"
                            value=""
                            required 
                        />
                    </div>
                    <div class="form-group">
                        <label for="email">E-Mail</label>
                        <input
                            type="email"
                            name="email"
                            class="form-control"
                            placeholder="E-Mail eingeben"
                            value=""
                            required
                        />
                    </div>
                    <div class="form-group">
                        <label for="subject">Betreff</label>
                        <input
                            type="text"
                            name="subject"
                            class="form-control"
                            placeholder="Betreff eingeben"
                            value="" 
                        />
                    </div>
                    <div class="form-group">
                        <label for="message">Nachricht</label>
                        <textarea
                            type="textarea"
                            name="message"
                            class="form-control"
                            value="">
                        </textarea>
                    </div>
                    <button
                        type="submit"
                        name="Submit"
                        value="send"
                        class="btn btn-primary">
                        Senden
                    </button>
                </fieldset>
            }
        </div> <!-- /.container -->
    </section> <!-- /.formulate -->
    

    FormController.cs:

    using System;
    using System.Net;
    using System.Net.Mail;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    using Umbraco.Cms.Core.Models.PublishedContent;
    using Umbraco.Cms.Core.Routing;
    using Umbraco.Cms.Core.Web;
    using Umbraco.Extensions;
    
    namespace Umbraco9.Web.Controllers
    {
        public class FormController : Controller
        {
            private readonly IUmbracoContextAccessor _umbracoContextAccessor;
            private readonly IPublishedUrlProvider _publishedUrlProvider;
    
            public FormController(IUmbracoContextAccessor umbracoContextAccessor, IPublishedUrlProvider publishedUrlProvider)
            {
                _umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor));
                _publishedUrlProvider = publishedUrlProvider ?? throw new ArgumentNullException(nameof(publishedUrlProvider));
            }
    
            [HttpGet]
            public IActionResult RenderForm()
            {
                return PartialView("ContactForm");
            }
    
            [HttpPost]
            [ValidateAntiForgeryToken]
            public IActionResult SubmitForm(IFormCollection form)
            {
                string firstName = form["firstName"];
                string lastName = form["lastName"];
                string email = form["email"];
                string subject = form["subject"];
                string message = form["message"];
    
                // E-Mail-Einstellungen
                string senderEmail = ""; // Absender-E-Mail-Adresse
                string receiverEmail = ""; // Empfänger-E-Mail-Adresse
                string password = ""; // E-Mail-Passwort
                string smtpHost = "send.smtp.com"; // SMTP-Host
                int smtpPort = 25; // SMTP-Port
    
                // E-Mail erstellen
                MailMessage mail = new MailMessage();
                mail.From = new MailAddress(senderEmail);
                mail.To.Add(receiverEmail);
                mail.Subject = subject;
                mail.Body = $"Name: {firstName} {lastName}\nEmail: {email}\n\n{message}";
    
                // SMTP-Client erstellen und E-Mail senden
                SmtpClient smtpClient = new SmtpClient(smtpHost, smtpPort);
                smtpClient.Credentials = new NetworkCredential(senderEmail, password);
                smtpClient.EnableSsl = true;
                smtpClient.Send(mail);
    
                // Umleitung zur aktuellen Umbraco-Seite
                IPublishedContent currentPage = _umbracoContextAccessor.GetRequiredUmbracoContext().PublishedRequest.PublishedContent;
                string currentPageUrl = _publishedUrlProvider.GetUrl(currentPage, UrlMode.Absolute);
                return Redirect(currentPageUrl);
            }
        }
    }
    
  • Huw Reddick 1929 posts 6697 karma points MVP 2x c-trib
    Jun 07, 2023 @ 16:06
    Huw Reddick
    0

    Hi,

    could it be this Html.BeginUmbracoForm("SubmitForm", "FormController", FormMethod.Post) normaly you would just refer to controllers by the name without the controller part, so Html.BeginUmbracoForm("SubmitForm", "Form", FormMethod.Post)

    However this may cause a problem being refered to as Form, propably best to give it a different name, although it may be OK

  • apload-gmbh 39 posts 109 karma points
    Jun 09, 2023 @ 08:06
    apload-gmbh
    0

    Hi Huw

    I also came up with that idea, but it didn't work out.

    But thanks for your help!

  • Huw Reddick 1929 posts 6697 karma points MVP 2x c-trib
    Jun 09, 2023 @ 08:10
    Huw Reddick
    100

    try decalring your controller as a surface controller, does that make any difference?

    public class FormController : SurfaceController
    
  • Huw Reddick 1929 posts 6697 karma points MVP 2x c-trib
    Jun 09, 2023 @ 08:19
    Huw Reddick
    0

    Another think to try is change the definition of the SubmitForm action, I have just checked some of my code, and in places I had to do this

    SubmitForm([FromForm] IFormCollection formModel)
    

    To determine if that is the issue, you could change it to simple

    `SubmitForm(Object formModel)` 
    

    if it then hits the controller it is the definition that is not correct for the object being passed. If it still doesn't hit the controller action then it is a routing issue. (you should not need to add a route to the startup.cs

  • apload-gmbh 39 posts 109 karma points
    Jun 09, 2023 @ 12:39
    apload-gmbh
    0

    That also didn't work out. So it means, that there is a routing issue in my solution?

  • apload-gmbh 39 posts 109 karma points
    Jun 09, 2023 @ 12:41
    apload-gmbh
    0

    My firts attempt was to create a SurfaceController. But i had to much issues in dependencies and couldn't make it work...

  • Huw Reddick 1929 posts 6697 karma points MVP 2x c-trib
    Jun 09, 2023 @ 12:48
    Huw Reddick
    0

    It looks like it yes, one thing to check, when the form is rendered, what is it's action set to?

  • apload-gmbh 39 posts 109 karma points
    Jun 09, 2023 @ 13:30
    apload-gmbh
    0

    In the

    action is just /kontaktformular/.

  • Huw Reddick 1929 posts 6697 karma points MVP 2x c-trib
    Jun 09, 2023 @ 14:28
    Huw Reddick
    0

    That doesn't look right, it should be /Form/SubmitForm if that is your controller an action names.

    I have had this issue before with forms in viewcomponents, try channging your form to the following

    @using (Html.BeginUmbracoForm<FormController>("SubmitForm", null,null,FormMethod.Post))
    
  • apload-gmbh 39 posts 109 karma points
    Jun 12, 2023 @ 07:58
    apload-gmbh
    0

    Hi Huw I tried again to edit my controller to a SurfaceController and now it seems to work! Thank you so much for your help!!!

Please Sign in or register to post replies

Write your reply to:

Draft