Override Action Method Using Plugin into nopCommerce3.8
Take a look at this simple tutorial that demonstrates how to override the action method in nopCommerce 3.8.
Join the DZone community and get the full member experience.
Join For FreeThis article shows you how to override the action method in nopCommerce 3.8 version. In this article, I am going to override the Contact us form to extend its functionality. But this action method override way is not worked over seo URL (route value) like product URL, category URL, etc.
Override Contact Us page
Now, I am going to show how to override the Contact us page using plugin. This Contact us form has fields like name
, emailid
, and content
, but I want to add one more field, contact no
, that will help me to get the contact details of the person who is going to post this form.
You may also enjoy: A Beginner's Guide to Overriding Methods
For this feature, I am going to add one project into the plugin folder and add the ContactusController.cs, RouteProvider.cs, ContactUsModel.cs, ContactUs.cshtml, app.config, description.txt, OverrideActionMethodProvider.cs, packages.config, and web.config. For now, I refer to the Nop.Plugin.ExternalAuth.Facebook
plugin.
My plugin structure is as below:
I have created:
- ContactSscontroller.cs => for the Contact us form
get
orpost
method. - RouteProvider.cs => is used to override the route URL of Contact us. If the user calls the Contact us URL, then our plugin form will be displayed instead of default nopCommerce form (action method).
- ContactUsmodel.cs => to add one more property of
contact no
. - ContactUs.cshtml => This view file displays content of Contact us form.
- OverrideActionMethodProvider.cs => creating a method for the
install
anduninstall
process for plugin
ContactUsmodel.cs model file. I have added my new property into this model. I have used the existing ContactUsModel
of nopCommerce.
xxxxxxxxxx
1 using Nop.Web.Framework;
2
3 namespace Nop.Plugin.OverrideActionMethod.Models
4 {
5 public class ContactUsModel : Nop.Web.Models.Common.ContactUsModel
6 {
7 [NopResourceDisplayName("Account.Fields.Phone")]
8 public string PhoneNo { get; set; }
9 }
10 }
RouteProvider.cs routeProvider
file overrides the existing route value:
1 using Nop.Web.Framework.Localization;
2 using Nop.Web.Framework.Mvc.Routes;
3 using System.Web.Routing;
4 using System.Linq;
5
6 namespace Nop.Web.Infrastructure
7 {
8 public partial class RouteProvider : IRouteProvider
9 {
10 public void RegisterRoutes(RouteCollection routes)
11 {
12 routes.Remove(routes.FirstOrDefault(c => (c as Route).Url == "contactus"));
13 routes.MapLocalizedRoute("ContactUs",
14 "contactus",
15 new { controller = "ContactUs", action = "ContactUs" },
16 new[] { "Nop.Plugin.OverrideActionMethod.Controllers" });
17 }
18 }
19 }
I have removed the existing route value of Contact us and added my Contact us route value. I have mentioned my controller name, action method name, and namespace for this.
Contactus.cshtml view file:
xxxxxxxxxx
1 ContactUsModel
2 Nop.Plugin.OverrideActionMethod.Models
3 Nop.Web.Framework
4 Nop.Web.Framework.UI
5 Nop.Web.Framework.Security.Captcha
6 {
7 Layout = "~/Views/Shared/_ColumnsOne.cshtml";
8
9 //title
10 Html.AddTitleParts(T("PageTitle.ContactUs").Text);
11 //page class
12 Html.AppendPageCssClassParts("html-contact-page");
13 }
14 <div class="page contact-page">
15 <div class="page-title">
16 <h1> ("PageTitle.ContactUs")</h1>
17 </div>
18 <div class="page-body">
19 .Action("TopicBlock",
20 "Topic", new { systemName = "ContactUs" })
21 .Widget("contactus_top")
22 (Model.SuccessfullySent)
23 {
24 <div class="result">
25 .Result
26 </div>
27 }
28 else
29 {
30 using (Html.BeginForm("ContactUsSend",
31 "ContactUs", FormMethod.Post, new { id = "form" }))
32 {
33 .AntiForgeryToken()
34 var validationSummary = Html.ValidationSummary(true);
35 if (!MvcHtmlString.IsNullOrEmpty(validationSummary))
36 {
37 <div class="message-error"></div>
38 }
39 <div class="fieldset">
40 <div class="form-fields">
41 <div class="inputs">
42 .LabelFor(model => model.FullName)
43 .TextBoxFor(model => model.FullName,
44 new { = "fullname",
45 placeholder = T("ContactUs.FullName.Hint") })
46 .RequiredHint()
47 .ValidationMessageFor(model => model.FullName)
48 </div>
49 <div class="inputs">
50 .LabelFor(model => model.Email)
51 .TextBoxFor(model => model.Email,
52 new { = "email",
53 placeholder = T("ContactUs.Email.Hint") })
54 .RequiredHint()
55 .ValidationMessageFor(model => model.Email)
56 </div>
57 (Model.SubjectEnabled)
58 {
59 <div class="inputs">
60 .LabelFor(model => model.Subject)
61 .TextBoxFor(model => model.Subject,
62 new { = "subject",
63 placeholder = T("ContactUs.Subject.Hint") })
64 .RequiredHint()
65 .ValidationMessageFor(model => model.Subject)
66 </div>
67 }
68 <div class="inputs">
69 .LabelFor(model => model.Enquiry)
70 .TextAreaFor(model => model.Enquiry,
71 new { = "enquiry",
72 placeholder = T("ContactUs.Enquiry.Hint") })
73 .RequiredHint()
74 .ValidationMessageFor(model => model.Enquiry)
75 </div>
76 (Model.DisplayCaptcha)
77 {
78 <div class="captcha-box">
79 .Raw(Html.GenerateCaptcha())
80 </div>
81 }
82
83 <div class="inputs">
84 .LabelFor(model => model.PhoneNo)
85 .TextBoxFor(model => model.PhoneNo)
86 .ValidationMessageFor(model => model.PhoneNo)
87 </div>
88 </div>
89 </div>
90 <div class="buttons">
91 <input type="submit" name="send-email"
92 class="button-1 contact-us-button"
93 value="@T("ContactUs.Button")" />
94 </div>
95 }
96 }
97 .Widget("contactus_bottom")
98 </div>
99 </div>
I have only added phone no text into this view file and changed the form post action method name to post into my controller.
ContactUsController.cs
xxxxxxxxxx
1 using Nop.Core;
2 using Nop.Core.Domain.Common;
3 using Nop.Core.Domain.Messages;
4 using Nop.Plugin.OverrideActionMethod.Models;
5 using Nop.Services.Customers;
6 using Nop.Services.Localization;
7 using Nop.Services.Logging;
8 using Nop.Services.Messages;
9 using Nop.Web.Controllers;
10 using Nop.Web.Framework.Security;
11 using Nop.Web.Framework.Security.Captcha;
12 using System;
13 using System.Linq;
14 using System.Web.Mvc;
15
16 namespace Nop.Plugin.OverrideActionMethod.Controllers
17 {
18 public class ContactUsController : BasePublicController
19 {
20 #region Fields
21
22 private readonly ILocalizationService _localizationService;
23 private readonly IWorkContext _workContext;
24 private readonly IStoreContext _storeContext;
25 private readonly IQueuedEmailService _queuedEmailService;
26 private readonly IEmailAccountService _emailAccountService;
27 private readonly ICustomerActivityService _customerActivityService;
28 private readonly EmailAccountSettings _emailAccountSettings;
29 private readonly CommonSettings _commonSettings;
30 private readonly CaptchaSettings _captchaSettings;
31
32 #endregion
33
34 #region Constructors
35
36 public ContactUsController(
37 ILocalizationService localizationService,
38 IWorkContext workContext,
39 IStoreContext storeContext,
40 IQueuedEmailService queuedEmailService,
41 IEmailAccountService emailAccountService,
42 ICustomerActivityService customerActivityService,
43 EmailAccountSettings emailAccountSettings,
44 CommonSettings commonSettings,
45 CaptchaSettings captchaSettings)
46 {
47 this._localizationService = localizationService;
48 this._workContext = workContext;
49 this._storeContext = storeContext;
50 this._queuedEmailService = queuedEmailService;
51 this._emailAccountService = emailAccountService;
52 this._customerActivityService = customerActivityService;
53 this._emailAccountSettings = emailAccountSettings;
54 this._commonSettings = commonSettings;
55 this._captchaSettings = captchaSettings;
56 }
57
58 #endregion
59
60 #region Methods
61
62 public ActionResult ContactUs()
63 {
64 var model = new ContactUsModel
65 {
66 Email = _workContext.CurrentCustomer.Email,
67 FullName = _workContext.CurrentCustomer.GetFullName(),
68 SubjectEnabled = _commonSettings.SubjectFieldOnContactUsForm,
69 DisplayCaptcha = _captchaSettings.Enabled &&
70 _captchaSettings.ShowOnContactUsPage
71 };
72 return View("~/Plugins/Plugin.OverrideActionMethod/Views/ContactUs/
73 ContactUs.cshtml", model);
74 }
75
76 [HttpPost]
77 [PublicAntiForgery]
78 [CaptchaValidator]
79 public ActionResult ContactUsSend(ContactUsModel model, bool captchaValid)
80 {
81 //validate CAPTCHA
82 if (_captchaSettings.Enabled &&
83 _captchaSettings.ShowOnContactUsPage && !captchaValid)
84 {
85 ModelState.AddModelError
86 ("", _captchaSettings.GetWrongCaptchaMessage(_localizationService));
87 }
88
89 if (ModelState.IsValid)
90 {
91 var phoneNo = model.PhoneNo;
92 string email = model.Email.Trim();
93 string fullName = model.FullName;
94 string subject = _commonSettings.SubjectFieldOnContactUsForm ?
95 model.Subject :
96 string.Format(_localizationService.GetResource
97 ("ContactUs.EmailSubject"),
98 _storeContext.CurrentStore.GetLocalized(x => x.Name));
99
100 var emailAccount = _emailAccountService.GetEmailAccountById
101 (_emailAccountSettings.DefaultEmailAccountId);
102 if (emailAccount == null)
103 emailAccount =
104 _emailAccountService.GetAllEmailAccounts().FirstOrDefault();
105 if (emailAccount == null)
106 throw new Exception("No email account could be loaded");
107
108 string from;
109 string fromName;
110 string body = Core.Html.HtmlHelper.FormatText
111 (model.Enquiry, false, true, false, false, false, false);
112 //required for some SMTP servers
113 if (_commonSettings.UseSystemEmailForContactUsForm)
114 {
115 from = emailAccount.Email;
116 fromName = emailAccount.DisplayName;
117 body = string.Format("<strong>From</strong>:
118 {0} - {1}<br /><br />{2}",
119 Server.HtmlEncode(fullName),
120 Server.HtmlEncode(email), body);
121 }
122 else
123 {
124 from = email;
125 fromName = fullName;
126 }
127 _queuedEmailService.InsertQueuedEmail(new QueuedEmail
128 {
129 From = from,
130 FromName = fromName,
131 To = emailAccount.Email,
132 ToName = emailAccount.DisplayName,
133 ReplyTo = email,
134 ReplyToName = fullName,
135 Priority = QueuedEmailPriority.High,
136 Subject = subject,
137 Body = body,
138 CreatedOnUtc = DateTime.UtcNow,
139 EmailAccountId = emailAccount.Id,
140 });
141
142 model.SuccessfullySent = true;
143 model.Result = _localizationService.GetResource
144 ("ContactUs.YourEnquiryHasBeenSent");
145
146 //activity log
147 _customerActivityService.InsertActivity("PublicStore.ContactUs",
148 _localizationService.GetResource("ActivityLog.PublicStore.ContactUs"));
149
150 return View("~/Plugins/Plugin.OverrideActionMethod/
151 Views/ContactUs/ContactUs.cshtml", model);
152 }
153
154 model.DisplayCaptcha = _captchaSettings.Enabled &&
155 _captchaSettings.ShowOnContactUsPage;
156 return View("~/Plugins/Plugin.OverrideActionMethod/Views/ContactUs/
157 ContactUs.cshtml", model);
158 }
159 #endregion
160 }
161 }
This controller helps me to display my Contact us form and get the form detail into my end to get new property value.
I hope you've now understood how to override the action method using plugin in nopcommerce3.8. I have attached the source code of this plugin so you will be able to get a better idea about this.
Published at DZone with permission of sangeet shah. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments