I'm using DNN 9.3.2 and Chris Hammond's module template to create a custom module. When I load the module onto a page without visibility restrictions, it does not render. The Event Log does not contain any errors after installation or rendering of said page.
Since this is my first DNN MVC module, I'm thinking this has to do with the following controller class I've created:
[DnnHandleError]
public class SignupController : DnnController
{
// GET: Signup
[ModuleAction(ControlKey = "Edit", TitleKey = "AddItem")]
public ActionResult Index()
{
var signups = OnboardingManager.Instance.GetOnboardings(ModuleContext.ModuleId);
return View(signups);
}
[HttpPost]
[DotNetNuke.Web.Mvc.Framework.ActionFilters.ValidateAntiForgeryToken]
public ActionResult Edit(Models.Onboarding onboarding)
{
ProPayService service = new ProPayService();
OnboardingManager.Instance.CreateOnboarding(onboarding);
service.MerchantSignupForProPayAsync();
return RedirectToDefaultRoute();
}
public ActionResult Edit(int onboardingId = -1)
{
DotNetNuke.Framework.JavaScriptLibraries.JavaScript.RequestRegistration(CommonJs.DnnPlugins);
var userlist = UserController.GetUsers(PortalSettings.PortalId);
var users = from user in userlist.Cast<UserInfo>().ToList()
select new SelectListItem { Text = user.DisplayName, Value = user.UserID.ToString() };
ViewBag.Users = users;
var onboarding = (onboardingId == -1) ? new Models.Onboarding{ModuleId = ModuleContext.ModuleId} : OnboardingManager.Instance.GetOnboarding(onboardingId, ModuleContext.ModuleId);
return View(onboarding);
}
}
The service class referenced above is defined as follows:
public class ProPayService
{
private static HttpClient _httpClient = new HttpClient();
//private readonly string _baseUrl = "https://xmltestapi.propay.com/ProPayAPI";
Uri _baseUrl = new Uri("https://xmltestapi/propay.com/ProPayAPI");
public ProPayResponse MerchantSignupForProPayAsync()
{
SignupRequest signupRequest = new SignupRequest();
SignupResponse signupResponse = new SignupResponse();
HttpContent content = new StringContent(signupRequest.ToString());
CancellationToken cancellationToken = new CancellationToken();
var credentials = GetCredentials();
var responseBody = _httpClient.PutAsync(_baseUrl, content, cancellationToken).Result;
try
{
BuildMerchantTestData();
Console.WriteLine(responseBody);
Console.WriteLine(content);
if (WebRequest.Create(_baseUrl) is HttpWebRequest httpRequest)
{
httpRequest.Method = "PUT";
httpRequest.Headers.Add("accept", "applicaiton/json");
httpRequest.Headers.Add("Authorization", credentials);
}
//var httpRequest = new HttpRequestMessage(HttpMethod.Put, _baseUrl);
//httpRequest.Headers.Add("Authorization", credentials);
Console.WriteLine(signupResponse.Status);
}
catch (HttpRequestException e)
{
Console.WriteLine("\nException caught");
Console.WriteLine("Message: {0} ", e.Message);
}
return JsonConvert.DeserializeObject<ProPayResponse>(responseBody.Content.ReadAsStringAsync().Result);
}
private SignupRequest BuildMerchantTestData()
{
int moduleId = 0;
int OnboardingId = 0;
var result = OnboardingManager.Instance.GetOnboarding(OnboardingId, moduleId);
var onboardingList = new List<Models.Onboarding>();
var ownerList = new List<OwnerList>();
SignupRequest signupRequest = new SignupRequest();
if (result != null)
{
Debug.Assert(result != null, nameof(OnboardingList) + " != null");
Console.WriteLine("{0} {1}", result.Email, result.UserId);
List<Owner> owner1 = new List<Owner>
{
new Owner
{
FirstName = result.OwnerFirstName,
LastName = result.OwnerLastName,
Address = result.OwnerAddress,
City = result.OwnerCity,
State = result.OwnerRegion,
Zip = result.OwnerZipCode,
Country = result.OwnerCountry,
DateOfBirth = result.OwnerDob,
SSN = result.OwnerSsn,
Email = result.Email,
Percentage = result.OwnerPercentage,
Title = result.OwnerTitle
}
};
signupRequest = new SignupRequest
{
PersonalData = new PersonalData
{
FirstName = result.FirstName,
MiddleInitial = result.MiddleInitial,
LastName = result.Lastname,
DateOfBirth = result.DateOfBirth,
SocialSecurityNumber = result.Ssn,
SourceEmail = result.Email,
PhoneInformation =
new PhoneInformation
{ DayPhone = result.DayPhone, EveningPhone = result.EveningPhone },
},
InternationalSignUpData = null,
//InternationalSignUpData = new InternationalSignupData
//{
// DocumentExpDateString = result.DocumentExpDate,
// DocumentIssuingState = result.DocumentIssuingState,
// DocumentType = result.DocumentType,
// DriversLicenseVersion = result.DriversLicenseVersion,
// InternationalId = result.InternationalId,
// MedicareCardColor = result.MedicareCardColor,
// MedicareReferenceNumber = result.MedicareReferenceNumber
//},
NotificationEmail = result.Email,
SignupAccountData = new SignupAccountData
{
CurrencyCode = "USD",
//UserId = result.UserId.ToString(),
//PhonePIN = result.PhonePin,
//ExternalId = "12345",
Tier = "Test"
},
BusinessData =
new BusinessData
{
BusinessLegalName = result.BusinessLegalName,
DoingBusinessAs = result.DoingBusinessAs,
EIN = result.Ein,
MerchantCategoryCode = result.MerchantCategoryCode,
WebsiteURL = result.BusinessUrl,
BusinessDescription = result.BusinessDescription,
MonthlyBankCardVolume = result.MonthlyBankCardVolume ?? 0,
AverageTicket = result.AverageTicket ?? 0,
HighestTicket = result.HighestTicket ?? 0
},
Address = new Address
{
ApartmentNumber = result.Address1ApartmentNumber,
Address1 = result.Address1Line1,
Address2 = result.Address1Line1,
City = result.Address1City,
State = result.Address1State,
Country = result.Address1Country,
Zip = result.Address1ZipCode
},
MailAddress = new Address
{
ApartmentNumber = result.OwnerApartmentNumber,
Address1 = result.OwnerAddress,
Address2 = result.OwnerAddress2,
City = result.OwnerCity,
State = result.OwnerRegion,
Country = result.OwnerCountry,
Zip = result.OwnerZipCode
},
BusinessAddress =
new Address
{
ApartmentNumber = result.BusinessApartmentNumber,
Address1 = result.BusinessAddressLine1,
Address2 = result.BusinessAddressLine2,
City = result.BusinessCity,
State = result.BusinessState,
Country = result.BusinessCountry,
Zip = result.BusinessZipCode
},
//CreditCardData = new CreditCardData
//{
// NameOnCard = result.NameOnCard,
// CreditCardNumber = result.CreditCardNumber, // test card number
// ExpirationDate = result.ExpirationDate
//},
BankAccount =
new BankAccount
{
AccountCountryCode = result.BankAccount1CountryCode,
BankAccountNumber = result.BankAccount1Number,
RoutingNumber = result.BankAccount1RoutingNumber,
AccountOwnershipType = result.BankAccount1OwnershipType,
BankName = result.BankAccount1BankName,
AccountType = "Checking",
//AccountType = result.BankAccount1Type,
AccountName = result.BankAccount1Name,
Description = result.BankAccount1Description
},
//SecondaryBankAccount =
// new BankAccount
// {
// AccountCountryCode = result.BankAccount2CountryCode,
// BankAccountNumber = result.BankAccount2Number,
// RoutingNumber = result.BankAccount2RoutingNumber,
// AccountOwnershipType = result.BankAccount2OwnershipType,
// BankName = result.BankAccount2BankName,
// AccountType = result.BankAccount2Type,
// AccountName = result.BankAccount2Name,
// Description = result.BankAccount2Description
// },
//GrossBillingInformation = new GrossBillingInformation
//{
// GrossSettleAddress = new Address
// {
// Address1 = result.OwnerAddress,
// Address2 = result.OwnerAddress2,
// ApartmentNumber = result.OwnerApartmentNumber,
// City = result.OwnerCity,
// Country = result.OwnerCountry,
// State = result.OwnerRegion,
// Zip = result.OwnerZipCode
// },
// GrossSettleBankAccount = new BankAccount
// {
// AccountCountryCode = "USA",
// AccountName = result.BankAccount1Name,
// AccountOwnershipType = result.BankAccount1OwnershipType,
// AccountType = result.BankAccount1Type,
// BankAccountNumber = result.BankAccount1Number,
// BankName = result.BankAccount1BankName,
// Description = result.BankAccount1Description,
// RoutingNumber = result.BankAccount1RoutingNumber
// },
// GrossSettleCardData = new CreditCardData
// {
// CreditCardNumber = result.CreditCardNumber,
// ExpirationDate = result.ExpirationDate,
// NameOnCard = result.NameOnCard
// }
//},
//FraudDetectionData = new FraudDetectionData
//{
// MerchantSourceIp = result.MerchantSourceIp,
// ThreatMetrixPolicy = result.ThreatMetrixPolicy,
// ThreatMetrixSessionId = result.SessionId
//},
//PaymentMethodId = result.PaymentMethodId,
//PaymentBank = new BankAccount
//{
// AccountName = result.PaymentBankAccountName,
// AccountCountryCode = result.PaymentBankCountryCode,
// AccountOwnershipType = result.PaymentBankOwnershipType,
// AccountType = result.PaymentBankAccountType,
// BankAccountNumber = result.PaymentBankAccountNumber,
// BankName = result.PaymentBankName,
// Description = result.PaymentBankAccountDescription,
// RoutingNumber = result.PaymentBankRoutingNumber
//}
BeneficialOwnerData = new BeneficialOwnerData
{
OwnerCount = "1",
Owners = owner1
}
};
Console.WriteLine(JsonConvert.SerializeObject(signupRequest));
}
//return new SignUpRequest();
return signupRequest;
}
private static string GetCredentials()
{
var termId = "myId"; // put affiliate term id here, if you have it
var certString = "myCert"; // put affiliate cert string here
var encodedCredentials = Convert.ToBase64String(Encoding.Default.GetBytes(certString + ":" + termId));
var credentials = $"Basic {encodedCredentials}";
return credentials;
}
}
The DNN manifest file is defined as follows:
<dotnetnuke type="Package" version="5.0">
<packages>
<package name="Onboarding" type="Module" version="00.00.01">
<friendlyName>Onboarding</friendlyName>
<description>Onboarding</description>
<iconFile>~/Icons/Sigma/Software_32X32_Standard.png</iconFile>
<owner>
<name>SocialBodega.com</name>
<organization>SocialBodega.com</organization>
<url>https://www.socialbodega.com/</url>
<email>[email protected]</email>
</owner>
<license src="License.txt"></license>
<releaseNotes src="ReleaseNotes.txt"></releaseNotes>
<dependencies>
<dependency type="CoreVersion">08.00.00</dependency>
</dependencies>
<components>
<component type="Script">
<scripts>
<basePath>DesktopModules\MVC\Onboarding</basePath>
<script type="Install">
<path>Providers\DataProviders\SqlDataProvider</path>
<name>00.00.01.SqlDataProvider</name>
<version>00.00.01</version>
</script>
<script type="UnInstall">
<path>Providers\DataProviders\SqlDataProvider</path>
<name>Uninstall.SqlDataProvider</name>
<version>00.00.01</version>
</script>
</scripts>
</component>
<component type="ResourceFile">
<resourceFiles>
<basePath>DesktopModules/MVC/Onboarding</basePath>
<resourceFile>
<name>Resources.zip</name>
</resourceFile>
</resourceFiles>
</component>
<component type="Module">
<desktopModule>
<moduleName>Onboarding</moduleName>
<foldername>Onboarding</foldername>
<businessControllerClass>SocialBodega.Onboarding.Components.FeatureController</businessControllerClass>
<supportedFeatures />
<moduleDefinitions>
<moduleDefinition>
<friendlyName>Onboarding</friendlyName>
<defaultCacheTime>0</defaultCacheTime>
<moduleControls>
<!--<moduleControl>
<controlKey />
<controlSrc>SocialBodega.Onboarding.Controllers/Item/Index.mvc</controlSrc>
<supportsPartialRendering>False</supportsPartialRendering>
<controlTitle />
<controlType>View</controlType>
<iconFile />
<helpUrl />
<viewOrder>0</viewOrder>
</moduleControl>-->
<moduleControl>
<controlKey/>
<controlSrc>SocialBodega.Onboarding.Controllers/Signup/Index.mvc</controlSrc>
<supportPartialRendering>False</supportPartialRendering>
<controlTitle/>
<controlType>View</controlType>
<iconFile/>
<helpUrl/>
<viewOrder>0</viewOrder>
<supportsPopUps>True</supportsPopUps>
</moduleControl>
<moduleControl>
<controlKey>Edit</controlKey>
<controlSrc>SocialBodega.Onboarding.Controllers/Signup/Edit.mvc</controlSrc>
<supportsPartialRendering>False</supportsPartialRendering>
<controlTitle>Edit Signups</controlTitle>
<controlType>Edit</controlType>
<iconFile />
<helpUrl />
<viewOrder>0</viewOrder>
<supportsPopUps>True</supportsPopUps>
</moduleControl>
<moduleControl>
<controlKey>Settings</controlKey>
<controlSrc>SocialBodega.Onboarding.Controllers/Settings/Settings.mvc</controlSrc>
<supportsPartialRendering>False</supportsPartialRendering>
<controlTitle>Onboarding Settings</controlTitle>
<controlType>Edit</controlType>
<iconFile />
<helpUrl />
<viewOrder>0</viewOrder>
</moduleControl>
</moduleControls>
</moduleDefinition>
</moduleDefinitions>
</desktopModule>
</component>
<component type="Assembly">
<assemblies>
<assembly>
<name>Onboarding.dll</name>
<path>bin</path>
</assembly>
</assemblies>
</component>
</components>
</package>
</packages>
</dotnetnuke>
Are there changes I should make to my above controller to ensure that the module renders properly? Or are there other items I should review to further diagnose the issue?
Update: After making a change to the DNN manifest as per comment, I am now unable to add the module to the page and receive the following in admin log:
AbsoluteURL:
DefaultDataProvider:DotNetNuke.Data.SqlDataProvider, DotNetNuke
ExceptionGUID:e229902b-051f-459e-9647-28adcd0d4f50
AssemblyVersion:
PortalId:-1
UserId:-1
TabId:-1
RawUrl:
Referrer:
UserAgent:
ExceptionHash:OLQuqVQLbGm0IndDqnMOfMf2C3Q=
Message:Error Creating BusinessControllerClass
'SocialBodega.Onboarding.Components.FeatureController, SocialBodega.Onboarding' of module(Onboarding) id=(422) in tab(41) and portal(0)
StackTrace:
at DotNetNuke.Services.Search.ModuleIndexer.ThrowLogError(ModuleInfo module,
Exception ex)
InnerMessage:Value cannot be null. Parameter name: type
InnerStackTrace:
at System.Activator.CreateInstance(Type type, Boolean nonPublic) at
System.Activator.CreateInstance(Type type) at
DotNetNuke.Services.Search.ModuleIndexer.GetModuleList(Int32 portalId)
Source:DotNetNuke
My revised DNN Manifest is listed below:
<dotnetnuke type="Package" version="5.0">
<packages>
<package name="Onboarding" type="Module" version="00.00.01">
<friendlyName>Onboarding</friendlyName>
<description>Onboarding</description>
<iconFile>~/Icons/Sigma/Software_32X32_Standard.png</iconFile>
<owner>
<name>SocialBodega.com</name>
<organization>SocialBodega.com</organization>
<url>https://www.socialbodega.com/</url>
<email>[email protected]</email>
</owner>
<license src="License.txt"></license>
<releaseNotes src="ReleaseNotes.txt"></releaseNotes>
<dependencies>
<dependency type="CoreVersion">08.00.00</dependency>
</dependencies>
<components>
<component type="Script">
<scripts>
<basePath>DesktopModules\MVC\Onboarding</basePath>
<script type="Install">
<path>Providers\DataProviders\SqlDataProvider</path>
<name>00.00.01.SqlDataProvider</name>
<version>00.00.01</version>
</script>
<script type="UnInstall">
<path>Providers\DataProviders\SqlDataProvider</path>
<name>Uninstall.SqlDataProvider</name>
<version>00.00.01</version>
</script>
</scripts>
</component>
<component type="ResourceFile">
<resourceFiles>
<basePath>DesktopModules/MVC/Onboarding</basePath>
<resourceFile>
<name>Resources.zip</name>
</resourceFile>
</resourceFiles>
</component>
<component type="Module">
<desktopModule>
<moduleName>Onboarding</moduleName>
<foldername>Onboarding</foldername>
<businessControllerClass>SocialBodega.Onboarding.
Components.FeatureController,
SocialBodega.Onboarding</businessControllerClass>
<supportedFeatures />
<moduleDefinitions>
<moduleDefinition>
<friendlyName>Onboarding</friendlyName>
<defaultCacheTime>0</defaultCacheTime>
<moduleControls>
<!--<moduleControl>
<controlKey />
<controlSrc>SocialBodega.Onboarding.Controllers/Item/Index.mvc
</controlSrc>
<supportsPartialRendering>False</supportsPartialRendering>
<controlTitle />
<controlType>View</controlType>
<iconFile />
<helpUrl />
<viewOrder>0</viewOrder>
</moduleControl>-->
<moduleControl>
<controlKey/>
<controlSrc>SocialBodega.Onboarding.Controllers/Signup/Index.mvc
</controlSrc>
<supportPartialRendering>False</supportPartialRendering>
<controlTitle/>
<controlType>View</controlType>
<iconFile/>
<helpUrl/>
<viewOrder>0</viewOrder>
<supportsPopUps>True</supportsPopUps>
</moduleControl>
<moduleControl>
<controlKey>Edit</controlKey>
<controlSrc>SocialBodega.Onboarding.Controllers/Signup/Edit.mvc
</controlSrc>
<supportsPartialRendering>False</supportsPartialRendering>
<controlTitle>Edit Signups</controlTitle>
<controlType>Edit</controlType>
<iconFile />
<helpUrl />
<viewOrder>0</viewOrder>
<supportsPopUps>True</supportsPopUps>
</moduleControl>
<moduleControl>
<controlKey>Settings</controlKey>
<controlSrc>SocialBodega.Onboarding.Controllers/Settings/Settings.mvc
</controlSrc>
<supportsPartialRendering>False</supportsPartialRendering>
<controlTitle>Onboarding Settings</controlTitle>
<controlType>Edit</controlType>
<iconFile />
<helpUrl />
<viewOrder>0</viewOrder>
</moduleControl>
</moduleControls>
</moduleDefinition>
</moduleDefinitions>
</desktopModule>
</component>
<component type="Assembly">
<assemblies>
<assembly>
<name>Onboarding.dll</name>
<path>bin</path>
</assembly>
</assemblies>
</component>
</components>
</package>
Update2 I upgraded to DNN 9.4 late last week and took the advice received to comment out all code in my view and just render a label. This worked!! Thus, my view syntax is as per below:
@inherits
DotNetNuke.Web.Mvc.Framework.DnnWebViewPage
<DotNetNuke.Collections.PagedList<SocialBodega.Onboarding.
Models.Onboarding>>
@using System.Linq
@using System.Text.RegularExpressions
@using DotNetNuke.Collections
@using DotNetNuke.Entities.Urls
@using DotNetNuke.Web.Mvc.Helpers
<div id="[email protected]">
@if (Model == null|| !Model.Any())
{
<p>@Dnn.LocalizeString("NoSignups")</p>
}
else
{
<ul>
@foreach (var onboarding in Model)
{
<li>
<h3>@onboarding.FirstName</h3>
<div>@onboarding.OnboardingId</div>
@{
if (Dnn.ModuleContext.IsEditable)
{
<div>
<a href="@Url.Action("Edit","Signup", new{ctl = "Edit", onboardingId = onboarding.OnboardingId, })">@Dnn.LocalizeString("EditItem")</a>
</div>
}
}
</li>
}
</ul>
}
</div>
@*@Html.Label("Testing 123");*@
When I build the solution, it succeeds but I do receive 16 error messages in Visual Studio 2019 to the effect of:
Error CS0012 The type 'WebViewPage<>' is defined in an assembly that is
not referenced. You must add a reference to assembly 'System.Web.Mvc,
Version=5.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
1_desktopmodules_mvc_onboarding_Views_Signup_Index.cshtml
C:\websites\dnndev.me\DesktopModules\Onboarding\Views\Signup\Index.cshtml
I've added said assembly to web.config in the Views folder of the module and also to the main DNN web.config at C:\websites.dnndev.me using the following:
<compilation debug="true" targetFramework="4.7.2">
<assemblies>
<add assembly="System.Web.Mvc, Version = 5.1.0.0, Culture = neutral, PublicKeyToken = 31bf3856ad364e35"/>
<add assembly ="netstandard, Version = 2.0.0.0, Culture = neutral, PublicKeyToken = cc7b13ffcd2ddd51"/>
</assemblies>
</compilation>
How do I prevent the errors from being thrown and ensure that my view renders as desired?