Sunday, November 29, 2020

Showing Wildfires on Google Maps with Blazor Server

One of my favorite web programming YT channels presented this idea during the past weeks. Traversy Media's tutorial was about showing Wildfires using React and Google Maps.

Please, have a look on his approach:


As I am checking out Blazor Server, I decided to give it a try, to reproduce something similar, using C# and Blazor Server.

The aim of this app is just to show the wildfires of the world, on a map centered on California, using the above mentioned technlogies.

Prerequisites:

- basics of Blazor server

- intermediate C#

- using free component for maps from Radzen Blazor

- using Nasa Web Api

The application is live: wildfires.zoltanhalasz.net

Github Repo with code: https://github.com/zoltanhalasz/WildFiresBlazor

Steps for the application:

1. Create a Blazor Server App with Asp.Net Core 3.1

2. Install Blazor Radzen for Server: https://blazor.radzen.com/get-started

3. See the tutorial for the Httpclient in Blazor from Tim Corey: 



4. Our Api will be inserted in appsettings.json

  "NasaAPI": "https://eonet.sci.gsfc.nasa.gov/api/v2.1/categories/8"

Please visit the link to examine the structure of json data, that will be deserialized.

5. Create folder Data in the project and insert class named Event.cs

Have a look on my approach, how to deserialize the json string coming from Nasa, by preparing the corresponding structure of classes.

6. The page with the wildfires, will be using Google Maps Component, please study that also on Radzon Blazor https://blazor.radzen.com/googlemap

7. The main logic of the display is presented in the Index.razor component. I will not reproduce it here, since would be just a copy paste from my repo.

I hope this was useful and somebody learnt a bit of Blazor from this.

Tuesday, October 6, 2020

Simple Cryptocurrency App With Blazor Server Incl Excel Export

For some reason, I started to like developing with Blazor Server, mainly because the rapidity and simplicity of development. I tend to use some free component libraries to speed up development. I still want to mention that all my experience with Blazor Server is only on tutorial/experimental level.

This is just an application to learn Blazor Server, and familiarize with Cryptocurrencies, it has no other purpose.



Prerequisites for this app:

- basic Blazor Server (See my previous tutorials)

- install Radzen Components in your app see https://blazor.radzen.com/get-started

- using the C# wrapper for CoinPaprika Api (to get cryptocurrency info) https://github.com/MSiccDev/CoinpaprikaAPI

Code repository: https://github.com/zoltanhalasz/BlazorCoins

Application is live under: https://blazorcoins.zoltanhalasz.net/

The app works the following way:

1. the route /cointable will show the top 100 crypto currencies, using the API



2. clicking the detail per each currency, the route /coinhistory will show a chart and historical data for selected currency



3. the route /coingrid will show exactly the same info as 1) only in a Radzen Grid




Bonus:

The app has export excel capabilities, which can be achieved doing the following:

1. create wwwroot/js/DownloadExcel.js

function saveAsExcel(fileName, byteContent) {

    var link = document.createElement('a');

    link.download = fileName;

    console.log(fileName);

    link.href = 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,' + byteContent;

    document.body.appendChild(link);

    link.click();

    document.body.removeChild(link);

}

2. include the file reference at the bottom of _Host.cshtml, just below the other scripts

    <script src="/js/DownloadExcel.js"></script>

3. install EPPlus, latest, via Nuget Packages

4. in page /cointable (or where you need to export from excel), insert the markup for a button

 <button class="btn btn-primary" @onclick="GenerateExcel">Download</button>

5. include the following in the top of the page you want to use Excel Export :

@inject IJSRuntime iJSRuntime;

6. Write the handlers for GenerateExcel, in the code section of the page where you have the list that you need to export in Excel

private async Task DownloadExcel(IJSRuntime myJSRuntime)

    {

        byte[] file;


        if (coinList == null) return;


        ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

        using (var package = new ExcelPackage())

        {

            var worksheet = package.Workbook.Worksheets.Add("Sheet1");

            worksheet.Cells.LoadFromCollection(coinList, true);

            package.Save();

            file = package.GetAsByteArray();

        }

        await myJSRuntime.InvokeAsync<List<CoinInfo>>("saveAsExcel", "CoinList.xlsx", Convert.ToBase64String(file));

    }


    private async Task GenerateExcel()

    {

        await DownloadExcel(iJSRuntime);

    }



Monday, October 5, 2020

Upload and Download Pdf files to/from MS SQL Database using Razor Pages

As most of my project applications are business related, and I still plan to create such applications, thought about the idea to store attached pdf invoices in a database.

Below is a simple sample application, using Asp.Net Core 3.1 and Razor Pages, for an invoice management system with pdf file upload/download.

The Github repo for the application is here.

The application is also online, can be tested out: https://uploadfile.zoltanhalasz.net/

Prerequisites:

- beginner/intermediate Razor Pages for Asp.Net Core, see study material here https://mydev-journey.blogspot.com/2019/11/razor-pages-not-for-shaving.html

- intermediate C# and SQL

- some basic Entity Framework Core.

My sources for learning were:

- an MVC version for the upload: https://tutexchange.com/how-to-upload-files-and-save-in-database-in-asp-net-core-mvc/

- the download, was discovered using various C# resources.

Firstly, we create the database named UploadFile and then a table:

CREATE TABLE [dbo].[Invoices](

[Id] [int] IDENTITY(1,1) NOT NULL,

[Number] [int] NOT NULL,

[Date] [datetime] NOT NULL,

[Value] [decimal](18, 2) NOT NULL,

[Attachment] [varbinary](max) NULL,

 CONSTRAINT [PK_Invoices] PRIMARY KEY CLUSTERED ([Id] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

Steps for creating the application:
1. Create an Asp.Net Razor Pages project
.Net Core version 3.1

2. Scaffold the database into the models using https://marketplace.visualstudio.com/items?itemName=ErikEJ.EFCorePowerTools or simply copy my Data folder that is adding the necessary data structures 
Alternatively, you can use the more traditional caffolding method: https://www.entityframeworktutorial.net/efcore/create-model-for-existing-database-in-ef-core.aspx

Make sure that the model and dbContext  (called UploadFileContext) will be stored in Data folder.

3. Add to Startup.cs, ConfigureServices method:

 services.AddDbContext<UploadfileContext>(options =>
                  options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),           
                    sqlServerOptions => sqlServerOptions.CommandTimeout(100))
                    );

4. Create and Index page, that will show the list of invoices
- the page cshtml file will contain the listing of the invoices, together with the download, upload, and delete functionalities


- the PageModel class will contain the methods to deal with:

a. download the pdf file from the database:

public async Task<IActionResult> OnPostDownloadAsync(int? id)
{
            var myInv = await _context.Invoices.FirstOrDefaultAsync(m => m.Id == id);
            if (myInv == null)
            {
                return NotFound();
            }

            if (myInv.Attachment== null)
            {
                return Page();
            }
            else
            {
                byte[] byteArr = myInv.Attachment;
                string mimeType = "application/pdf";
                return new FileContentResult(byteArr, mimeType)
                {
                    FileDownloadName = $"Invoice {myInv.Number}.pdf"
                };
            }
}

b. delete attached file from database:

public async Task<IActionResult> OnPostDeleteAsync(int? id)
{
            var myInv = await _context.Invoices.FirstOrDefaultAsync(m => m.Id == id);
            if (myInv == null)
            {
                return NotFound();
            }

            if (myInv.Attachment == null)
            {
                return Page();
            }
            else
            {
                myInv.Attachment = null;
                _context.Update(myInv);
                await _context.SaveChangesAsync();
            }

            Invoices = await _context.Invoices.ToListAsync();
            return Page();
}

5. Add a page to create Invoice Data (this can be done via Razor Pages scaffolding),

and 

6. Create an Upload Page that will help with pdf file upload

This will have the file with markup, cshtml, containing the html tags for the form:
@page
@model UploadFile.Pages.UploadModel
@{
}

<h1>Upload Invoice</h1>


<hr />
<div class="row">
    <div class="col-md-4">
        <form method="post" enctype="multipart/form-data">
            <div class="form-group">
                <div class="col-md-10">
                    <p>Upload file</p>
                    <input type="hidden" asp-for="@Model.ID" value="@Model.myID" />
                    <input asp-for="file" class="form-control" accept=".pdf" type="file" />
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-10">
                    <input class="btn btn-success" type="submit" value="Upload" />
                </div>
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

And for the PageModel class, we will have the handler to deal with the file uploaded:

public class UploadModel : PageModel
{                  

        private readonly UploadfileContext _context;

        public UploadModel(UploadfileContext context)
        {
            
            _context = context;
        }
        public int ? myID { get; set; }

        [BindProperty]
        public IFormFile file { get; set; }

        [BindProperty]
        public int ? ID { get; set; }
        public void OnGet(int? id)
        {
            myID = id;
        }

        public async Task<IActionResult> OnPostAsync()
        {
            if (file != null)
            {
                if (file.Length > 0 && file.Length < 300000)
                {
                    var myInv = _context.Invoices.FirstOrDefault(x => x.Id == ID);

                    using (var target = new MemoryStream())
                    {
                        file.CopyTo(target);
                        myInv.Attachment = target.ToArray();
                    }

                    _context.Invoices.Update(myInv);
                    await _context.SaveChangesAsync();
                }

            }

            return RedirectToPage("./Index");
        }

}


7. The end result will be like this:





Sunday, June 7, 2020

Weather App With Google Maps Demo Using Blazor Server, HttpClient and Radzen Components

My favorite teacher for C# on Youtube is Tim Corey, and his latest material concerns HttpClient, using a Weather Forecast Api.
See his material, and check the code provided, as this is a the beginning step towards our application. My application is live: https://httpclientwithmaps.azurewebsites.net
Final project is: https://github.com/zoltanhalasz/HttpClientWithMaps The way the final application works:
1. map is centered in Central Europe
2. click on the map- we will see the neighboring cities with available weather data
3. click on a red bullet - (marker) - the available weather forecast will be displayed in the table on the right.

Prerequisites:
1. Dotnet Blazor Server Side Basics - see my previous tutorial
2. Check Radzen Controls for Maps - check the source
https://blazor.radzen.com/googlemap
3. Check the Weather Api - it's the same source as mentioned by Tim
https://www.metaweather.com/api/
Steps to follow:
A. Take the sample application as starting point from Tim (it's a Blazor Server Application)
B. Add Blazor Radzen to the project, as presented below:
https://blazor.radzen.com/get-started
C. Add the following Changes, described below:

1. Add another class to Model folder to track the locations (which will be represented as red dots on the map)
    public class LocationModel
    {
        public int distance { get; set; }      
        public string title { get; set; }
        public string location_type { get; set; }
        public int woeid { get; set; }
        public string latt_long { get; set; }
        public double latt { get; set; }
        public double _long { get; set; }
    }

2. The code is commented, to understand the main functions, you can copy the WeatherData.razor page content into your project. This contains the functionality described in the beginning.

Please check the map functionality and weather api in the prerequisites to understand it.

3. The left menu is slightly simplified versus the Tim version, you can copy or leave it.

Enjoy! Let me know your comments.

Friday, May 1, 2020

Simple Todo App with Blazor Server and Material Blazor

In order to make my journey in C# more interesting, I insert small projects where I can learn new things. The new target is now Blazor Server, a very interesting Web Technology from Microsoft.

I am trying to find small things to learn and add them to a bigger project later this year, perhaps.
My main tutors on the net were Tim Corey, and maybe Nick Chapsas. You can search them on youtube, they have great content.

The new application I have created is a regular todo app which uses:
- blazor server
- material design https://www.matblazor.com/
- a simple list (no database)

Prerequisites:
- asp.net core 3.1 installed on your machine
- intermediate C# and html

Code is under:
https://github.com/zoltanhalasz/TodoList_BlazorServer.git

The application is live: https://todolist-blazorserver.zoltanhalasz.net/todos

You can add material design to a blazor server project:
1.Install-Package MatBlazor
2.Add @using MatBlazor in main _Imports.razor
3.add to _Host.cshtml (head section)
<script src="_content/MatBlazor/dist/matBlazor.js"></script>
<link href="_content/MatBlazor/dist/matBlazor.css" rel="stylesheet" />

The toaster is added to the todo page: see instructions at: https://www.matblazor.com/Toast

I will explain some of the code and application below.

A. The main model class for the todos:


public class TodoModel
{
public int Id { get; set; }

public string Todo { get; set; }

public DateTime Deadline { get; set; }

public bool IsCompleted { get; set; }

}

B. The layout:
Please read the below examples
https://www.matblazor.com/TextField
https://www.matblazor.com/Checkbox
https://www.matblazor.com/DatePicker
https://www.matblazor.com/Button
See list of icons available:
https://www.matblazor.com/Icon
Toast, see tutorial example:
https://www.matblazor.com/Toast

C. The code-behind:

D. Final result: