Saturday, January 25, 2020

AG-Grid Tutorial With Asp.Net Core Razor Pages - Part 1


Besides DataTables.js, I always wanted to check Ag-Grid, which is another great Javascript Grid solution for the front-end. As my apps are from the business world, and have many tables, I wanted to see how AG-Grid would look like in Asp.Net Razor pages.


I quickly checked their Javascript documentation, and prepared a short tutorial, firstly for myself.
The material is based on the existing Datatables tutorial, from my previous posts. It uses an in-memory database and context, injected in the page model.

Please check the following, before starting the tutorial:
1. general introduction: https://www.ag-grid.com/javascript-grid/
2. see previous tutorial, which this one builds upon: https://mydev-journey.blogspot.com/2019/12/datatablejs-tutorial-for-net-core-razor_11.html
3. working example of the tutorial: https://ag-grid1.zoltanhalasz.net/
4. code repo for the tutorial:(zipped) https://drive.google.com/open?id=1BXYkn5RwHnC4w8USCeIBCV0lsDGi-qFh

Explanation of the project:
a. Base class for the application, identical with datatable tutorial above
 public class InvoiceModel
    {
        [JsonProperty(PropertyName = "ID")]
        public int ID { get; set; }

        [JsonProperty(PropertyName = "InvoiceNumber")]
        public int InvoiceNumber { get; set; }

        [JsonProperty(PropertyName = "Amount")]
        public double Amount { get; set; }
        [JsonProperty(PropertyName = "CostCategory")]
        public string CostCategory { get; set; }
        [JsonProperty(PropertyName = "Period")]
        public string Period { get; set; }
     

    }
b. Context for in-memory database, idem

 public class InvoiceContext : DbContext
    {
        public InvoiceContext(DbContextOptions<InvoiceContext> options)
            : base(options)
        {
        }

        public DbSet<InvoiceModel> InvoiceTable { get; set; }
    }

c. In the Pages/Shared folder, we will edit the _Layout page
insert the following stylesheet links specific to AG-grid, just before </head>
    <link rel="stylesheet" href="https://unpkg.com/ag-grid-community/dist/styles/ag-grid.css">
    <link rel="stylesheet" href="https://unpkg.com/ag-grid-community/dist/styles/ag-theme-balham.css">

d. The index page, will have the following methods:

 public class IndexModel : PageModel
    {
        private InvoiceContext _context;

        public List<InvoiceModel> InvoiceList;
        public IndexModel(InvoiceContext context)
        {
            _context = context;
        }

        // this will populate the page, if you want to show the table using the list (with foreach)
        public async Task<IActionResult> OnGet()
        {
            InvoiceList = _context.InvoiceTable.ToList();
            return Page();
        }

        //method to provide list in json format, for the ag-grid
        public JsonResult OnGetArrayData()
        {
            InvoiceList = _context.InvoiceTable.ToList();

            return new JsonResult(InvoiceList);
        }


    }

e. the html razor file, will contain the javascript code, based on the tutorial from ag-grid page
@page
@model IndexModel
@{
    Layout = "_Layout";
}

@*//script used to load the grid*@
<script src="https://unpkg.com/ag-grid-community/dist/ag-grid-community.min.noStyle.js"></script>
<h1>Hello from ag-grid!</h1>

<div id="myGrid" style="height: 600px;width:800px;" class="ag-theme-balham"></div>

<script type="text/javascript" charset="utf-8">
    // specify the columns
    var columnDefs = [
        { headerName: "InvoiceNumber", field: "InvoiceNumber" },
        { headerName: "Amount", field: "Amount" },
        { headerName: "CostCategory", field: "CostCategory" },
        { headerName: "Period", field: "Period" },
    ];

    // let the grid know which columns to use
    var gridOptions = {
        columnDefs: columnDefs,
        defaultColDef: {
            sortable: true,
            filter: true
        },
        rowClassRules: {
        // row style function
            'bigexpense-warning': function(params) {
                var numExpense = params.data.Amount;
                return  numExpense > 20 && numExpense <= 50;
            },
            // row style expression
            'bigexpense-breach': 'data.Amount > 50',
            'bigexpense-ok': 'data.Amount <=20'
        }
    };

    // lookup the container we want the Grid to use
    var eGridDiv = document.querySelector('#myGrid');

    // create the grid passing in the div to use together with the columns & data we want to use
    new agGrid.Grid(eGridDiv, gridOptions);

    agGrid.simpleHttpRequest({ url: './Index?handler=ArrayData' }).then(function (data) {
        gridOptions.api.setRowData(data);
    });

</script>

f. create the gridformat.css file in the folder wwwroot/css
include the following in this file
.ag-theme-balham .bigexpense-warning {
    background-color: sandybrown !important;
}

.ag-theme-balham .bigexpense-breach {
    background-color: lightcoral !important;
}

.ag-theme-balham .bigexpense-ok {
    background-color: mediumseagreen !important;
}

- in order to be able to populate the rowClassRules with valid css formatting classes
- include the reference to gridformat.css in the _Layout file, just above the ag-grid css links

g. some description of the javascript in the index.cshtml

Grid is marked by id:

<div id="myGrid" style="height: 600px;width:800px;" class="ag-theme-balham"></div>
Column headers are defined by array:
 var columnDefs = [
        { headerName: "InvoiceNumber", field: "InvoiceNumber" },
        { headerName: "Amount", field: "Amount" },
        { headerName: "CostCategory", field: "CostCategory" },
        { headerName: "Period", field: "Period" },
    ];
Sorting and filtering (basic) is setup by:
defaultColDef: {
            sortable: true,
            filter: true
        },

Double click on the row headers will sort the column.
There is a basic text filter included.

The formatting of rows, where the invoice Amount is between certain values
 rowClassRules: {
        // row style function
            'bigexpense-warning': function(params) {
                var numExpense = params.data.Amount;
                return  numExpense > 20 && numExpense <= 50;
            },
            // row style expression
            'bigexpense-breach': 'data.Amount > 50',
            'bigexpense-ok': 'data.Amount <=20'
        }

If you check the simpleHttpRequest function it's called on the handler defined in the pagemodel of the index page:

'./Index?handler=ArrayData'

The final result will be:


Tuesday, January 21, 2020

Missing Pieces in My Learning for 2020

If you read my posts here, it can be seen that my main technology used is Microsoft's .Net with C#.
My main apps are WPF, with Dapper ORM/SQL, and a small module in Asp.Net core Razor pages. But I still feel I have many missing parts in my learning process. I am finding the following tutorials really interesting to pursue, and cover these areas. I started them, but didn't go through them in detail. I am glad I found these, and this is the plan for me during the first half of 2020.



A. Identity Framework for Asp.Net Core.
I did some small tutorials this far on this topic, and lately I found this one. Code Maze is the best at C# tutorials, and this is my next one on Identity:
https://code-maze.com/identity-asp-net-core-project/
I feel there are missing pieces for me in this framework, and please let me have new materials if you find some.

B. Entity Framework Core
I used EF Core in my Asp.Net web project, but I still think that there are things to be learnt here. I found Tim's newest tutorial on this, quickly checked it but didn't have time to go deeply... Another one to check more in detail.
https://www.youtube.com/watch?v=qkJ9keBmQWo

C. Asynchronous C# with Async/Await
I started using this in my Asp and WPF project, and indeed it added some responsiveness to my apps. Need to study this deeper. Any ideas on this are welcome!

D. Logging in Asp.Net Core.
I never used this in my apps, but I plan to. The greatest source for this will be my newly purchased course on Asp.Net core 3: https://code-maze.com/ultimate-aspnet-core-3-web-api/

E. Check out Blazor, especially server side, later on, this year.

F. Some more Javascript on the front-end, and then my framework of choice, Angular. I am very behind in my learning with Angular, partly because I have to work on my projects. Currently I use some JQuery tools on my Asp.net project, like datatables.js, pivotjs, chart.js, and I really like what I discovered. Any new ideas are welcome.

Monday, January 13, 2020

Google Sheets with .Net Core Razor Pages CRUD Tutorial



In my research related to Asp.Net core, I came across a simple example using Google Sheets (spreadsheet) integrated into a .net core app. Actually, in the past days I  met a programmer friend who explained another app of his, that uses a google spreadsheet for back-end. That's why I decided to give it a try, check the below tutorial and adapt it to a full CRUD.

https://dottutorials.net/google-sheets-read-write-operations-dotnet-core-tutorial/

Please note that the above is a console app, and mine is a Razor pages CRUD, with added functionality, using the basic points from the above, but also extending the logic of it.

The initial settings are very well explained in the above tutorial, so you can check and follow how to create a google API and credentials etc, add nuget package for your app, which are the starting point for my app.

For our example, create a second sheet called Sheet2, which will contain a list of invoices, as presented in my sheet (see link, only read-only access granted).

My CRUD application is running under:
https://googlesheets.azurewebsites.net/InvoiceList

a. The base class for the invoice list looks as below:

public class InvoiceModel
    {
        public int Id { get; set; }
        public int InvoiceNumber { get; set; }
        public string CostCategory { get; set; }
        public string Period { get; set; }
        public double Amount { get; set; }

    }
b. The additional work in my case is a service class that supplies the CRUD operations, just as seen below.

This service uses the google api for spreadsheets. My resource was the above mentioned tutorial, with some modifications, using stack overflow etc.

I will attach only the service class.
https://drive.google.com/open?id=1mjxgBa5n6C3zcZTsnNx8jgF8OOkbqgoq

Let me know if any of you need the full code of the app.

Monday, January 6, 2020

Reviewing Three Asp.Net Core Tutorials


In my process of learning, in parallel to my C# projects, I am going forward with Asp.Net core, researching current practice and future trends. I came across three interesting tutorials, that combine these.

I try to be less elaborate with the review, just not to confuse the reader with too many details. Try all tutorials, and provide your feedback about them! I am a fan of learning from multiple sources, gradually, increasing complexity and depth step by step.



A. https://codinginfinite.com/creating-admin-panel-asp-net-core-mvc-tutorial/#choosing-template

This one, is aiming to build a nice admin LTE background, and use several practical HTML/JS tips.

The part I liked in this tutorial:
1. uses MySQL instead of MS SQL, with EF Core
2. Introduces Logging
3. Uses admin lte template, with all css/js dependencies, and uses also a custom login page
4. provides code repo on GitHub.
5. I see this tutorial as the most impactful to my activities, due to the business-like layout and approach.

What I didn't like about this tutorial:
1. Towards the end of it, it becomes superficial in explanation, hard to follow and understand
2. When I started to host the published version - somehow the admin lte is not working, and displays a mess.
3. The Role-Based Authorization part - I am not able understand this, something more detailed and systematic is needed, with better, step-by step explanations.

B.https://www.jerriepelser.com/tutorials/airport-explorer/

This aims combining Asp.Net Core Razor pages with lots of javascript APIs from the internet, especially those focused on maps and geolocation. I find this tutorial very high quality and easy to follow.

The pros of this tutorial:
1. Combines lots of internet APIs together with Asp.Net Core/Razor
2. Easy to follow despite its complexity
3. Very high quality explanations and step-by-step approach;
4. Provides GitHub Repo with code.

Some of the hardships:
1. Some complexity especially on the Javascript part;
2. The libraries and .net core version seem to be old;

C. https://youtu.be/8DNgdphLvag
This is Tim Corey's next tutorial, an easy introduction to Blazor Server Side. This is some very new technology and his explanations are easy to follow and shared lots of best practices.

The pros:
1. Latest technology;
2. Very easy to follow, excellent explanation;
3. Shares some nice best practices with organizing the code and database access;
4. Code provided.

The cons:
1. The example seems to be very simplistic, I would like to see a more complex application presented.(maybe a next version for him)
2. The technology presented is still not widespread. Waiting to see how Blazor proves to be in 2020 and later. Clearly Blazor Server Side is more stable, but Client side is not yet production ready.

What kind of similar tutorials would you recommend? I am especially interested in the combination of html/js/css with Razor pages (not Blazor, yet) with a focus for business applications.