goldsim / website Goto Github PK
View Code? Open in Web Editor NEWSource code for the GoldSim.com website
Home Page: https://www.goldsim.com/
Source code for the GoldSim.com website
Home Page: https://www.goldsim.com/
Update the DotNetStandard
branch to use the latest version of all NuGet dependencies.
Braintree
4.14.0EPPlus
4.5.3.2Ignia.Topics[.*]
3.8.0-alpha.257Microsoft.ApplicationInsights[.*]
2.10.0Microsoft.AspNet[.*]
3.2.7Microsoft.Net.Compilers
3.2.1Microsoft.CodeDom.Providers.DotNetCompilerPlatform
2.0.1Netonsoft.Json
12.0.2NuGet.CommandLine
5.1.0System.Data.SqlClient
4.6.1System.Diagnostics.DiagnosticSource
4.5.1System.Runtime
4.3.1System.Security.Cryptography.*
4.3.*Some of the dash segments for the 1000k homepage video appear to have been corrupted. As a temporary fix, I've removed the 1000k video from the MPD
manifest. In the longer term, however, we should:
dash.js
to the latest version in case there are bug fixesMPD
manifestEstablish new ASP.NET Core views to provide the user interface for the forms.
The current forms use ASP.NET WebForm Web Controls wrapped up in User Controls to expose the user interface, centralize reusable components, and provide both client- and server-side form validation.
With ASP.NET Core, the forms will now use standard MVC views. Reusable components can be handled via either partial views or—if they need to be parameterized—Razor components or view components. Form validation can now be handled using a combination of POCO attribute annotations as well as Microsoft’s jQuery-Validation-Unobtrustive
library for client-side validation. With ASP.NET Core 3.0 specifically, the input controls can now use the built-in Razor components.
<partial for />
, <partial model />
and @Html.EditorFor()
[Range()]
approach isn't workingWeb
navigation? Perhaps with a TopicLookup
of root namespaces?CoreContract
, Profile
)EditorTemplate
sEmail.cshtml
for representing the general email templateOptionalContact
CoreContact
Contact
ExtendedContact
Address
Profile
ExtendedProfile
ModuleSelection
AcademicInstructor
AcademicStudent
Demo
Evaluation
Newsletter
Quote
Training
UserConference
gmail.com
).JQuery-Validate-Unobtrusive
classes._CoreContact
.This will likely represent the largest effort in the forms migration, since much of the legacy code won’t translate to the new format.
The current forms rely on ASP.NET WebForms to loop through the Request.Form
collection to process form values. In ASP.NET Core (as well as ASP.NET MVC Framework) the preferred approach is to instead map this input to binding models.
In ASP.NET Core 3.0 this also allows easy configuration of form validation and error messaging through the use of attributes.
There is a lot of overlap between the various GoldSim forms. Given this, a layered approach to creating binding models based on reusable POCOs is preferred. This allows new forms to be easily composed, without limiting extensibility.
CoreContact
Contact
ExtendedContact
ExtendedContact
Profile
ExtendedProfile
Address
ModuleSelection
TrialFormBindingModel
(ExtendedProfile
)DemoFormBindingModel
(ExtendedProfile
)AcademicFormBindingModel
(ExtendedProfile
)
InstructorAcademicFormBindingModel
StudentAcademicFormBindingModel
PurchaseBindingModel
QuoteFormBindingModel
PurchaseFormBindingModel
For more information, see the GoldSim.DotNetCore.Forms.DataModel.txt
file.
The forms have a number of small issues that should be resolved.
/Forms
, /Licenses
Previously, authentication was handled via ASP.NET WebForms's Membership APIs. Those are overkill for how few users we have, and are very dated on top of it. We need to find an alternative solution that's simpler.
Currently, the ConnectionStrings.config
is .gitignore
’d in order to ensure that the database password is not exposed publicly. Since we’re hosting on Azure Web Apps, however, a more elegant approach is to use the new(er) secrets format—which reads from the secrets.json
in the /Users
directory in development, and from Azure’s Connection Strings configuration on the server.
secrets.json
file on Visual Studiosecrete.json
fileConnectionStrings.config
This is associated with the .NET Core 3.x Migration project—but, technically, it can be done at any time.
Establish an ASP.NET Core 3.0 controller to handle the routing and processing of form requests.
In the current ASP.NET WebForms version of the GoldSim forms, there are a number of helper functions in the master template that are called by each form. These serialize the Request.Form
data into a Dictionary<>
and then use that to perform a series of actions, such as sending an email.
In the ASP.NET Core version, these helper functions will become actions on a new FormsController
class. These can continue to rely on raw HttpRequest.Form
content—or they can use Reflection
to loop over the properties of the binding model. Regardless, the content of the actions should remain largely the same, with some minor adjustments to accommodate changes to the .NET Core API.
{*path}
routing work if the FormsController
implements TopicController
and MapTopicRoute()
?FollowUpPage
nested under a FormPage
be routed to the TopicController.Index()
action?IReverseTopicMappingService
to support complex properties. E.g., [MapToParent(true)]
, with property name being relayed as the (optional) prefix via private MapAsync(ITopicBindingModel source, Topic target, string prefix)
.ViewResult
.Feature actions support the basic functionality of the form processing. New feature actions can be added in the future, as necessary, to extend the form behavior.
Topic
via IReverseTopicMappingService
HttpContext.Request.Form
Routing actions map to individual forms. The [get]
action maps a route to a view; the [post]
action composes a series of feature actions to process the customer request. These include:
AcademicInstructor
AcademicStudent
Demo
Evaluation
Newsletter
Quote
Training
UserConference
Most of the logic for the forms will be defined in the form binding models (#10) and their corresponding views (#12).
In ASP.NET MVC Framework, the navigation elements were handled by their own controller—LayoutController
—which is embedded using the @Html.Action()
helper, thus allowing the logic and model of the layout to be separated from the TopicController
and its models, views.
This approach is formalized in ASP.NET Core with the introduction of View Components, which achieves a similar approach by establishing a component format with their own controller-like backend code. And, unlike the @Html.Action()
approach, this avoids issues with e.g. the ITopicRoutingService
not being able to resolve a Topic
for the request.
To support this, the updated version of OnTopic 5.8.0 includes the following out-of-the-box ViewComponent
s in the Ignia.Topics.AspNetCore.Mvc
project:
MenuViewComponentBase<T>
NavigationTopicViewComponentBase<T>
PageLevelNavigationViewComponentBase<T>
These base classes provide much of the logic needed for implementation, thus simply requiring that implementors override them to specify GoldSim’s version of the INavigationTopicViewModel<T>
class, and moving the views to the appropriate folder.
Implementation requires the following steps:
Menu
and PageLevelNavigation
components to specify the GoldSim version of the INavigationTopicViewModel<T>
CallsToActionViewComponent
based on the NavigationTopicViewComponentBase<T>
FooterViewComponent
based on the NavigationTopicViewComponentBase<T>
/Views/Layout
To /Views/Shared/Components/
Migrate the primary website—including the OnTopic components—to ASP.NET Core 3.0.
While much of ASP.NET Core remains compatible with ASP.NET MVC Framework 5.x, there are some differences, especially in terms of how the application is declared, bootstrapped, and configured. There are also some (minor) differences in the Razor syntax.
csproj
file to Visual Studio 2017 formatProgram.cs
class for bootstrapping appStartup.cs
to ASP.NET Core formatDefaultControllerFactory
to IControllerActivator
TopicRepository
ambient contextwwwroot
@Html.Partial
to <partial />
tag helper@helper
s to HTML @functions
Most of these changes have all been demonstrated on the Topics-AspNetCore-Sample site—though that is still based on ASP.NET Core 2.0 and still needs to be upgraded to take advantage of e.g. new support for Razor outputting functions.
OnTopic 3.8.0 makes a breaking change to the LayoutController
by replacing the ITopicMappingService
dependency with a new IHierarchicalTopicMappingService<>
dependency. This centralizes a lot of the reusable logic for various LayoutController
implementations while, importantly, also handing over control over caching to the composition root, thus allowing a single LayoutController
to be used independent of whether or not the results need to be cached.
LayoutController
to use IHierarchicalTopicMappingService<>
GoldSimControllerFactory
to construct proper dependency graphTopicViewModel
to auto-initialize Children
so it can't be assigned toThere are a handful of style sheet issues exposed by the migration of the forms to ASP.NET Core 3 which need to be fixed prior to launch.
grid-container grid-x
The _forms.scss
file has a selector for radio buttons that assumes that the <label />
will come after the <input />
. This is fine for checkbox
s, which are also included in the selector. But it isn't the preferred pattern for radio buttons since it doesn't provide a convenient way of connecting the label with an individual radio button. Instead, with the new forms, we're using the following:
<label><input name="…" value="…" type="radio" />…</label>
Given this, the radio button selectors need to be updated to use .radio label+[type=radio]
instead of .radio [type=radio]+label
.
Currently, required labels are prefixed with an asterisk in the markup. We could continue to do this, but ideally we'd instead implement a simple CSS selector that prepends an asterisk to any labels associated with a required field. Worst case, we can annotate these as class="Required"
, but preferably we'll instead select against jQuery-Validation-Unobtrusive
's data-
attributes so that this requires minimal markup.
The new forms no longer use Ignia's client-side validation library for ASP.NET WebForms, instead using the out-of-the-box jQuery-Validation-Unobtrustive
library. This means that fields that fail form validation have different classes associated with them and, thus, are no longer being picked up by the appropriate styles in _forms.scss
. Styles should account for form fields, (new) inline errors, and validation summaries.
grid-container grid-x
If the PageBodySection
is overwritten, and the form is wrapped in a <section class="panel body">
, then everything renders and works properly. If, however, the form content is placed directly in the body, and is rendered in _Layout.cshtml
using @RenderBody()
, then the checkboxes (and their labels) stop working. The main difference here is that the <section />
is wrapped in:
<div class="grid-container">
<div class="grid-x">
@RenderBody()
</div>
</div>
It is unexpected that adding grid-container
and/or grid-x
would interfere with the checkboxes and their labels. This could suggest a problem in the selectors.
Prepare the OnTopic data structure for the inclusion of forms by introducing the following features.
The approach described below allows a /Forms
root to be created which will be populated by FormPage
topics. This will keep the forms in their current location, and allow them to be associated with their own Controller
instance (the FormController
). Each topic will map to an action on the FormController
—e.g., a Trial
topic will map to a Trial()
action—thus allowing individualized composition of actions. Each FormPage
should be configured with, at minimum, the Title
, SubTitle
, and Body
of the form page so that GoldSim staff can edit them directly via OnTopic.
FormContainer
(Container
) for housing form pages
FormPage
types to be created under FormContainer
FormPage
(Page
) for representing form pages
FollowUpPage
and Email
to be created under FormPage
FollowUpPage
(Page
) for representing follow-up pagesEmail
(Page
) for representing (tokenized) email markup/Forms
(FormContainer
)/Forms/{Form}
(FormPage
)/Forms/{Form}/{FollowUp}
(FollowUpPage
)/Forms/{Form}/{Email}
(Email
)FormPage
ConfigurationIdeally, the FormPage
content type would allow the following to be specified:
Note: If the above are completed, then we may be able to do away with having a unique action for each form on the
FormsController
. At minimum, we'd be able to centralize the logic for all of them into a child action.
In getting the DotNetCore
branch to an initial compiling state, a number of quick fixes were taken, especially in cases where legacy APIs were no longer available, and there was no (apparent) out of the box replacement.
These should be reevaluated to make certain a) that they indeed work as expected (and especially when the previous approach was intended to resolve an issue with the ASP.NET Framework), and b) there isn’t a more elegant approach in ASP.NET Core.
<partial />
in place of @RenderPage
(IndexedList
)Create an ASP.NET View Component that optionally displays an announcement.
/Components/AnnouncementViewComponent.cs
/Models/AnnouncementViewModel.cs
/Views/Shared/Components/Announcement/Default.cshtml
This approach will allow @rkossik to create announcements via the editor without developer intervention. This will also automate error-prone details due to layout shifts needed when the attaching the announcement to the footer.
The Announcement view component will be called from the following views:
/Views/Home/Home.csthtml
(for the homepage)/Views/Layout/_Layout.cshtml
(for the footer)The source data will be placed within Web:Home
Topic in the following (new) attributes:
AnnouncementText
(Text
type)AnnouncementUrl
(Text
type)Note: While there are multiple places where we could logically store this data, the homepage makes sense given that a) the announcement is displayed at the top of the homepage, and b) the homepage is already a custom
Home
content type descriptor, which can easily be extended. That said, this can be migrated without much impact in the future, if appropriate.
In addition to the above, we need to account for the layout shift in the Calls to Action view component. By default, this is anchored to the footer. When the announcement is in place, it should anchor to the announcement instead. An open challenge is how to relay this data to the Calls to Action view component, which uses the centralized NavigationViewModel
, making it difficult to extend.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.