Blog: Posts from 2019

Labels
AJAX(112) App Studio(7) Apple(1) Application Builder(245) Application Factory(207) ASP.NET(95) ASP.NET 3.5(45) ASP.NET Code Generator(72) ASP.NET Membership(28) Azure(18) Barcode(2) Barcodes(3) BLOB(18) Business Rules(1) Business Rules/Logic(140) BYOD(13) Caching(2) Calendar(5) Charts(29) Cloud(14) Cloud On Time(2) Cloud On Time for Windows 7(2) Code Generator(54) Collaboration(11) command line(1) Conflict Detection(1) Content Management System(12) COT Tools for Excel(26) CRUD(1) Custom Actions(1) Data Aquarium Framework(122) Data Sheet(9) Data Sources(22) Database Lookups(50) Deployment(22) Designer(177) Device(1) DotNetNuke(12) EASE(20) Email(6) Features(101) Firebird(1) Form Builder(14) Globalization and Localization(6) How To(1) Hypermedia(2) Inline Editing(1) Installation(5) JavaScript(20) Kiosk(1) Low Code(3) Mac(1) Many-To-Many(4) Maps(6) Master/Detail(36) Microservices(4) Mobile(63) Mode Builder(3) Model Builder(3) MySQL(10) Native Apps(5) News(18) OAuth(9) OAuth Scopes(1) OAuth2(13) Offline(20) Offline Apps(4) Offline Sync(5) Oracle(11) PKCE(2) Postgre SQL(1) PostgreSQL(2) PWA(2) QR codes(2) Rapid Application Development(5) Reading Pane(2) Release Notes(183) Reports(48) REST(29) RESTful(29) RESTful Workshop(15) RFID tags(1) SaaS(7) Security(81) SharePoint(12) SPA(6) SQL Anywhere(3) SQL Server(26) SSO(1) Stored Procedure(4) Teamwork(15) Tips and Tricks(87) Tools for Excel(2) Touch UI(93) Transactions(5) Tutorials(183) Universal Windows Platform(3) User Interface(338) Video Tutorial(37) Web 2.0(100) Web App Generator(101) Web Application Generator(607) Web Form Builder(40) Web.Config(9) Workflow(28)
Archive
Blog
Posts from 2019
Friday, February 8, 2019PrintSubscribe
Global Error Logging
The framework in the foundation of apps created with Code On Time provides a unified error reporting mechanism that can be utilized to perform a global exception logging.

Error Logging

Create the following table in your database to keep track of runtime errors.

create table Errors(
    ErrorID uniqueidentifier not null primary key,
    ErrorDate datetime default getdate(),
    UserName nvarchar(128),
    Details ntext
)

Select your project on the start page of the app builder and choose Visual Studio. Create a code file in the ~/App_Code/cust0m folder and enter the following code:

namespace MyCompany.Services
{
    public partial class ApplicationServices
    {
        protected override void HandleError(HttpContext context, Exception er)
        {
            // log all uncaught exceptions reported by application
            LogError(new JObject(), er);
        }

        public static Guid LogError(JObject errorDetails, Exception ex)
        {
            // add exception to the details
            var error = new JObject();
            error["message"] = ex.Message;
            error["type"] = ex.GetType().FullName;
            error["source"] = ex.Source;
            error["stack"] = ex.StackTrace;
            errorDetails["exception"] = error;
            
            // configure error details
            var errorID = Guid.NewGuid();
            var details = errorDetails.ToString();
            var userName = BusinessRulesBase.UserName;
            
            // log error in the database 
            using (var q = new SqlText(
                "insert into Errors(ErrorID, Details, UserName) " +
                "values(@ErrorID, @Details, @UserName) "))
                q.ExecuteNonQuery(new { errorID, details, userName });
            
            return errorID;
        }
    }
}

Error details inherited from the exception will be transcribed in JSON format.
Note that the partial class ApplicationServices is not available in the Trial Edition. You will need a commercial version of the app generator to override the methods of the partial framework classes.
Method ApplicationServices.HandleError is invoked by application framework when the incoming requests have resulted in the application exception that was not handled. The code above will automatically capture all uncaught exceptions. Create a data model for the Errors table and design your own GUI to allow administrative review of error messages.

Custom Error Reporting

Some exceptions are handled by the framework and reported to the end user to avoid rendering the application inoperable. For example, the error is reported to the user as-is if there was an exception when saving data. The user may cancel the data input form and continue working with the app.
Database engine error may be cryptic and impossible to decipher. Developer can choose to “translate” such errors to the user and/or log them in the database for review by administrator.
Create another “code” file in the ~/App_Code/custom folder of your app.
Enter the following code to replace the default error reporting by data controllers. We are using ApplicationServices.LogError method created above to log errors.

using MyCompany.Data;
using Newtonsoft.Json.Linq;
using System;
using System.Web;
using MyCompany.Services;

namespace MyCompany.Data
{
    public partial class Controller
    {
        protected override void HandleException(Exception ex, ActionArgs args, ActionResult result)
        {
            // by default the exception is reported to the user in result.Errors property
            base.HandleException(ex, args, result);
            // log error in the database
            var errorDetails = new JObject();
            errorDetails["args"] = JObject.FromObject(args);
            var errorID = ApplicationServices.LogError(errorDetails, ex);
            // replace the error message reported to the user with a custom error
            if (result.Errors.Count > 0)
            {
                result.Errors.Clear();
                result.Errors.Add(string.Format("Error {0}. Please contact the Help Desk.", errorID));
            }
        }
    }
}

Error details will include the JSON definition of arguments including field values that caused the exception.

From now on any errors reported to the user will appear like this:

An example of custom error reported to the user when saving data in the app created with Code On Time.

Monday, January 14, 2019PrintSubscribe
Faster Code Generation, Clear Filter Button, Bug Fixes

Release 8.7.8.0 introduces the following features, enhancements, and bug fixes:

  • (Touch UI) Ion “Clear” is displayed next to the "filter description" to allow one-click clearing of the filter.
    Clear button is displayed next to the filter in Touch UI apps created with Code On Time app builder.
  • (Touch UI) Lookup field tagged lookup-fetch-all will pull all values that match the user criteria. The default limit is 1000 items.
  • (Model Builder) List of models displays "last changed/sorted" button at the top of the list if five or more models are available. Clicking on the link will toggle the sort order of project models.
  • (Framework) Apps deployed to virtual folder correctly reference CSS resources from the root of the app.
  • (App Gen) XSLT transformations are performed in memory when output files already exist to eliminate writing to the file system. This speeds up production and compilation of projects.
  • (App Gen) Classic themes are not copied in projects based on Touch UI to speed up code generation.
  • (Framework) Default max upload size is set to 2,097,151 KB in apps created with Free Trial and Unlimited Edition.
  • (App Gen) Custom "code" business rules are automatically included in the class library of the projects when enabled.
  • (Project Designer) Duplicate fields are suppressed in "grid" views as well as in "form" views of controllers when developer drops duplicates on the corresponding configuration elements.
  • (Framework) Fixed VB compilation issues of Access Control List code.
  • (Framework) Renamed ApplicationServices.AuthorizationIsNotSupported to AuthorizationIsSupported and changed the codebase accordingly.
  • (Framework) Removed implicit dependency on membership support in the apps.
  • (Library Downloader) Uses GET requests to download the licensed content instead of POST.
  • (Framework) Auto-complete values in lookups are shown correctly when virtualization is enabled.
  • (Touch UI) Tag clear-all enables "clear" icon in the form. Clicking on the icon will "empty" all fields in the form. This feature is great in dashboards and custom search screens. The video tutorial is coming soon.
  • (Touch UI) Click on the "arrow right" next to the empty lookup fields will not open popup in webkit browsers and instead proceed directly to the lookup.
  • (ODP) Uses optimized method of data view location and avoids infinite cycling under certain conditions.
  • (Touch UI) Method $app.input.execute accepts values passed in options as array, single object with name/value properties, and also custom objects.
Labels: Release Notes