(MVC) MVC (2020)

Blazor syntax and opportunity (what missing in Blazor?)

In this page I want to create my view to Blazor syntax, opportunity and main programming techniques. Similar review I was written in 2002-year, when Microsoft was created NET Framework 1.1, Visual Basic 7 and Classic ASP.NET - Как я осваивал .NET-framework., Как я осваивал .NET-студию., Язык программирования VB.NET and when I made important step in my life - step from VB6 to VB7. Then in 2010 I made next important step in my life - moving from Classic ASP.NET to ASP.NET MVC - Мой первый сайт на MVC 3 Razor.

And now, in 2020, I'm reading current Microsoft documentation to this technology - MS ASP.NET.pdf trying to moving to this techniques and I want to write my small notice review of Blazor syntax and opportunity.


1. How Blazor work (Layout, SignaR, Static/dynamic page).

Because MS always doing one step forward and two step backward, Blazor is some kind of reincarnation of Classic ASP.NET. This is a good news for me, because MS agreed with my deep feeling, than ASP.NET MVC with complex and sophisticated frontend like Angular was bee greatest mistake. 2020 year is good time of return to Classic ASP.NET.

This is documentation of Blazor for Classic ASP.NET programmer. It contains only couple page, because we have always understanding this technology.



This is scheme to configuring common NET Core environment and Blazor start page.



You can see (and parse!) only static page in browser. In the screen below you can understand what in Layout (Master Page in term of Classic ASP.NET) or for russian speaking its named "плашка сайта".



If page rendering dynamically, you can not see HTML at all. And Browser developer tools nothing to show. But If you connect browser through proxy (How to debug SignalR application in Net Core 3.1), you can see full SignalR traffic.



2. C# expression.

In Blazor HTML-page we can use directly any C# C# statements, operators, variables as Blazor expression (after "@" without generic or after "@()"), this is MS description of Blazor Expression.





3. Rules to link own C# code with HTML.

We can inserting own C# code into Blazor lifeCycle in some place.


   1:          public virtual Task SetParametersAsync(ParameterView parameters);
   2:          protected virtual void BuildRenderTree(RenderTreeBuilder builder);
   3:          protected Task InvokeAsync(Action workItem);
   4:          protected Task InvokeAsync(Func<Task> workItem);
   5:          protected virtual void OnAfterRender(bool firstRender);
   6:          protected virtual Task OnAfterRenderAsync(bool firstRender);
   7:          protected virtual void OnInitialized();
   8:          protected virtual Task OnInitializedAsync();
   9:          protected virtual void OnParametersSet();
  10:          protected virtual Task OnParametersSetAsync();
  11:          protected virtual bool ShouldRender();
  12:          protected void StateHasChanged();


In Blazor we have some directives in HTML, for example in screen below you can see directive @OnClick. We can link own C# code by this way - assign string to directive.



Alternative way to link own C# function to HTML is Lambda expression @onclick=@(async ()=>await XXX(YYY))



This events calling in the green circle in diagram above, before OnAfterRendering events and this is MS description of ComponentBase context, available in C# code.



Unfortunately, Blazor not support Page OnLeave event, therefore need to emulate this event using Microsoft.AspNetCore.Components.Server.Circuits. How to do this please look in my code:

4. List of available HTML-event to link own handlers by C# code.

We have a lot of events to link own code, not only @OnClick.




Progress events
@onloadstartProgressEventArgs
@ontimeoutProgressEventArgs
@onabortProgressEventArgs
@onloadProgressEventArgs
@onloadendProgressEventArgs
@onprogressProgressEventArgs
@onerrorErrorEventArgs
General events
@onactivateEventArgs
@onbeforeactivateEventArgs
@onbeforedeactivateEventArgs
@ondeactivateEventArgs
@onendedEventArgs
@onfullscreenchangeEventArgs
@onfullscreenerrorEventArgs
@onloadeddataEventArgs
@onloadedmetadataEventArgs
@onpointerlockchangeEventArgs
@onpointerlockerrorEventArgs
@onreadystatechangeEventArgs
@onscrollEventArgs
Focus events
@onfocusFocusEventArgs
@onblurFocusEventArgs
@onfocusinFocusEventArgs
@onfocusoutFocusEventArgs
Mouse events
@onmouseoverMouseEventArgs
@onmouseoutMouseEventArgs
@onmousemoveMouseEventArgs
@onmousedownMouseEventArgs
@onmouseupMouseEventArgs
@onclickMouseEventArgs
@ondblclickMouseEventArgs
@oncontextmenuMouseEventArgs
@onwheelWheelEventArgs
@onmousewheelWheelEventArgs
Drag events
@ondragDragEventArgs
@ondragendDragEventArgs
@ondragenterDragEventArgs
@ondragleaveDragEventArgs
@ondragoverDragEventArgs
@ondragstartDragEventArgs
@ondropDragEventArgs
Clipboard events
@onbeforecopyEventArgs
@onbeforecutEventArgs
@onbeforepasteEventArgs
@oncopyClipboardEventArgs
@oncutClipboardEventArgs
@onpasteClipboardEventArgs
Keyboard events
@onkeydownKeyboardEventArgs
@onkeyupKeyboardEventArgs
@onkeypressKeyboardEventArgs
Input events
@onchangeChangeEventArgs
@oninputChangeEventArgs
@oninvalidEventArgs
@onresetEventArgs
@onselectEventArgs
@onselectstartEventArgs
@onselectionchangeEventArgs
@onsubmitEventArgs
Touch events
@ontouchcancelTouchEventArgs
@ontouchendTouchEventArgs
@ontouchmoveTouchEventArgs
@ontouchstartTouchEventArgs
@ontouchenterTouchEventArgs
@ontouchleaveTouchEventArgs
Pointer events
@ongotpointercapturePointerEventArgs
@onlostpointercapturePointerEventArgs
@onpointercancelPointerEventArgs
@onpointerdownPointerEventArgs
@onpointerenterPointerEventArgs
@onpointerleavePointerEventArgs
@onpointermovePointerEventArgs
@onpointeroutPointerEventArgs
@onpointeroverPointerEventArgs
@onpointerupPointerEventArgs
Media events
@oncanplayEventArgs
@oncanplaythroughEventArgs
@oncuechangeEventArgs
@ondurationchangeEventArgs
@onemptiedEventArgs
@onpauseEventArgs
@onplayEventArgs
@onplayingEventArgs
@onratechangeEventArgs
@onseekedEventArgs
@onseekingEventArgs
@onstalledEventArgs
@onstopEventArgs
@onsuspendEventArgs
@ontimeupdateEventArgs
@onvolumechange EventArgs
@onwaitingEventArgs

More detail about Event see please in MS Documentation ASP.NET Core Blazor event handling.

5. List of available Blazor directives.

This is list of Page-Directives - MS Description.

  • @attribute
  • @code
  • @implements
  • @inherits
  • @inject
  • @layout
  • @namespace
  • @page
  • @typeparam
  • @using

And example of use it.



Also there are 5 Html-Directives. @bind and @on is metadirectives, @on mention in section above, @attributes in section below.

  • @attributes
  • @bind
  • @on{event}
  • @key
  • @ref

Usually I always create my own HTML-helper (directives in Blazor terminology) How to create Razor html-helper in VB.NET, but at the moment I write this notice I don't understand how to do this in Blazor.

6. List of available Blazor attributes.

Property and method in C# code can be marked by some attributes Microsoft.AspNetCore.Components Namespace.

  • [BindElement]
  • [BindInputElement]
  • [CascadingParameter]
  • [EventHandler]
  • [Inject]
  • [Layout]
  • [Parameter]
  • [Route]

7. Blazor HTML-tags (builting component).

We have four group of Blazor tags in the standard blazor namespaces (selected in _Imports.razor):

  • @using Microsoft.AspNetCore.Authorization
  • @using Microsoft.AspNetCore.Components.Authorization
  • @using Microsoft.AspNetCore.Components.Forms
  • @using Microsoft.AspNetCore.Components.Routing
  • @using Microsoft.AspNetCore.Components.Web

That is:

  • <AuthorizeRouteView Authorizing= Context= DefaultLayout= NotAuthorized= RouteData= />
  • <AuthorizeView Authorized= Authorizing= ChildContent= Context= NotAuthorized= Policy= Resource= Roles= />

  • <CascadingAuthenticationState ChildContent= />
  • <CascadingValue ChildContent= IsFixed= Name= TValue= Value= />

  • <EditForm AdditionalAttributes= ChildContent= Context= EditContext= Model= />
  • <InputCheckbox AdditionalAttributes= Value= ValueChanged= ValueExpression= />
  • <InputDate AdditionalAttributes= ParsingErrorMessage= TValue= Value= ValueChanged= ValueExpression= />
  • <InputNumber AdditionalAttributes= ParsingErrorMessage= TValue= Value= ValueChanged= ValueExpression= />
  • <InputSelect AdditionalAttributes= ChildContent= TValue= Value= ValueChanged= ValueExpression= />
  • <InputText AdditionalAttributes= Value= ValueChanged= ValueExpression= />
  • <InputTextArea AdditionalAttributes= Value= ValueChanged= ValueExpression= />

  • <DataAnnotationsValidator />
  • <ValidationMessage AdditionalAttributes= For= TValue= />
  • <ValidationSummary AdditionalAttributes= Model= />

We can see example of using this tags in my public project templates:

8. Call Javascript from Blazor and call Blazor from Javascript.

In Blazor we can execute JS by the pattern below.



This is right way to calling JS.



But not standard library as jQuery and many other JS library has conflict with _framework/blazor.server.js, for example Pace.JS (because PACE.JS is part of blazor.server.js and all js-constants will be doubled). This message show PACE.JS, included in blazor.server.js



In opposite direction you can call Blasor component from JS.



9. jQuery support.

At the moment Blazor has 8 tags related to jQuery, but officially I don't see any documentation about its. Maybe this is only empty stubs for future.

  • <jq />
  • <jqScript />
  • <jqScriptCdnGoogle />
  • <jqScriptCdnMs />
  • <jqScriptMin />
  • <jqScriptUiCdnGoogle />
  • <jqScriptValidateCdnMs />
  • <jqScriptValidateUnobtrusiveCdnMs />

However I constantly use jQuery functionality in my Blazor projects and doing it in the same way - I use JS function getElementsByClassName

10. Two-way data binding.

There are two different type of binding - binding HTML-element and binding builting Blazor components This is pattern of binding Html-element. Any HTML property or component parameters can be binding to the same way, Data must be parameters to binding XXX and EventCallback XXXChanged.



Another type of binding (with another keyword) is binding builting Blazor components inside form tag, inside Blazor <EditForm> tag. Also inside form can be present various validation, include custom validation, see below Forms and Validation.



And third case of binging, this is component binding. In this approach I have created custom component based on HTML-element and in high level it raise EventCallback UserChanged(UserID).



Binding this component on page looks as:



See full opportunity of custom component below Custom component future.

11. Set style of HTML-elements.

There some way to manipulating style of HTML elements. This is a first way, for open submenu I adding class "In".



This is a second way:



And third way is create own function with manipulation styles by boolean parameters in code.


12. Forms and Validation.

There are some tags rendering to HTML-input elements.



DataAnnotation in Model is processing as usually automatically by DataAnnotationsValidator. And this is common patter to use it.



Instead MS DataAnnotationsValidator it's possible to create custom validation component in the pattern below, validator component nested from Abstract validator.



We can use form parameter Context, in this case we have opportunity to use many button with different function to the same form.



More details about validation see please in MS documentation - ASP.NET Core Blazor forms and validation and Forms and validation.

13. Custom component future.

Of course we can create own components because any RAZOR file is components. Nut if components has route "@page" it has own URL, otherwise this is control (it ASP.NET classic terminology).

Blazor component (control) has some special future:

  • we can pass parameters into controls by binging and special keyword @bind-ControlParameterName
  • we can pass events to control (EventCallback parameter type) and than control can be raise event and carry any data from control to parent form
  • if we can pass parameter to control by @bind-ControlParameterName we can bind in main form event inside control by keywords @bind-ControlParameterName:event or if we use inside control events with special suffix Changed than no need to bing control's events manually from calling form.

  • we can call method inside control by using keyword ref, read and write any data inside control if we have reference to control.
  • we can create list of control with key keyword
  • RenderTemplate is a elementary part of Blazor apps, this page show syntax to define RenderFragment statically and than clone it by mouse click. Second part of this page showing how to read existing RenderFragment and insert it in new place of page.
  • Page Template show how to create special type of component - template component. This component receive RenderFragment (named OneLi in my code) as parameters for template component (named Component7 in my code). Type of this parameters define inside template component by keywords TypeParam and can be set when you perform template component (in my code OneLi RenderFragment define as RenderFragment<MouseEventArgs>). You can set this renderFragment parameters inline in order to call template component, but more convenient way is set RenderFragment in XML. And Context keyword help to define my RenderFragment named OneLi.
  • CascadingValue and CascadingParameter is a opportunity to define common parameters (named CascadingPrm in my code) to any derived controls (component in Blazor terminology) without implicit definition this parameters for each call. This page also show how to create component dynamically and clone it to many instance.
  • Caprure unexpected attributes by attributes and CaptureUnmatchedValues

All this special future we can see in this my project template.

14. HttpContext in Blazor.

For each SPA page Blazor server has permanently SignalR connection and in existing connection we only can read connection paremeters by HttpAccessor. But any navigation to another page like NavigationManager.NavigateTo(URL, ForceReload=true) SignalR connection will be break and we can install any new connection parameters.

This opportunity I use to authentication, see my project template.


Even we can directly write to Browser like in simple ASP.NET, see this my project template.


Most programmer not understanding this simple Blazor future - why? Because this is common disadvantage of Dependency Injection technology. For example, you even add HttpAccessor, but you can not see property BodyWriter. Only after you add library Microsoft.AspNetCore.Http.Features needed property and methods will be appear.



Without dependency injection we simple was opened ObjectBrowser and was search needed symbol by seconds. But Nuget has millions and millions of libraries, how we will know what library contains needed method? Extension, extension and extension of existing framework is great advantage for framework developers but it not look greate for customer of expandable framework. Or need to create at least Object Browser for all nuget packages.

By the way dependency injection one of the common obstacle for fast programming, for example dumb Visual Studio not propose anything even in obviously case. But is it possible to remember any namespaces in millions on .Net framework classes?


15. NET Core tags and attributes.

We can imports all NET Core tags to blazor CHTML-file (not in Blazor !) - Tag Helpers in forms in ASP.NET Core, Built-in ASP.NET Core Tag Helpers.



After that will be accessible a lot of ancient (but useful HTML-helpers).



For example this helper generate input=text with additional attributes two-way binded to data.


@Html.EditorFor(model => model.YourProperty, new { htmlAttributes = new { @class="myCssClass", style="Width:100px" } })
@Html.ValidationSummary

Also there are more modern way to receive access to ASP.NET server functionality of this tags.


asp-action
<a asp-controller="Speaker" asp-action="Evaluations">Speaker Evaluations</a>
asp-controller
<a asp-controller="Speaker" asp-action="Index">All Speakers</a>
asp-area
<a asp-area="Sessions" asp-page="/Index">View Sessions</a>
asp-fragment
<a asp-controller="Speaker" asp-action="Evaluations" asp-fragment="SpeakerEvaluations">Speaker Evaluations</a>
asp-host
<a asp-protocol="https" asp-host="microsoft.com" asp-controller="Home" asp-action="About">About</a>
asp-protocol
<a asp-protocol="https" asp-controller="Home" asp-action="About">About</a>
asp-route
<a asp-route="speakerevals">Speaker Evaluations</a>
[Route("/Home/Test", Name = "Custom")]
asp-all-route-data
<a asp-route="speakerevalscurrent" asp-all-route-data="parms">Speaker Evaluations</a>
asp-route-*
<a href="/Speaker/Detail?speakerid=12">SpeakerId: 12</a>
asp-page
<a asp-page="/Attendee">All Attendees</a>
asp-page-handler
<a asp-page="/Attendee" asp-page-handler="Profile" asp-route-attendeeid="12">Attendee Profile</a>
  
asp-action
<button asp-controller="Home" asp-action="Index">Click Me</button>
<input type="image" src="..." alt="Or Click Me" asp-controller="Home" asp-action="Index">
<input type="submit" asp-controller="Home" asp-action="Index">Send</button>
<form asp-controller="Home" asp-action="Index">
asp-controller ...
asp-area ...
asp-page ...
asp-page-handler ...
asp-route ...
asp-route-{value} ...
asp-all-route-data ...
asp-fragment ...
cache-enabled
<cache enabled="true">
<distributed-cache name="MyCache" enabled="true">
cache-expires-on
<cache expires-on="@new DateTime(2025,1,29,17,02,0)">
<distributed-cache name="MyCache" expires-on="@new DateTime(2025,1,29,17,02,0)">
cache-expires-after
<cache expires-after="@TimeSpan.FromSeconds(120)">
<distributed-cache name="MyCache" expires-after="@TimeSpan.FromSeconds(120)">
cache-expires-sliding
<cache expires-sliding="@TimeSpan.FromSeconds(60)">
<distributed-cache name="MyCache" expires-sliding="@TimeSpan.FromSeconds(60)">
cache-vary-by-header
<cache vary-by-header="User-Agent">
<distributed-cache name="MyCache" vary-by-header="User-Agent">
cache-vary-by-query
<cache vary-by-query="Make,Model">
<distributed-cache name="MyCache" vary-by-query="Make,Model">
cache-vary-by-route
<cache vary-by-route="Make,Model">
<distributed-cache name="MyCache" vary-by-route="Make,Model">
cache-vary-by-cookie
<cache vary-by-cookie=".AspNetCore.Identity.Application">
<distributed-cache name="MyCache" vary-by-cookie=".AspNetCore.Identity.Application">
cache-vary-by-user
<cache vary-by-user="true">
<distributed-cache name="MyCache" vary-by-user="true">
cache-vary-by
<cache vary-by="@Model">
cache-priority
<cache priority="High">
<distributed-cache name="MyCache" priority="High">
environment-names
<environment names="Staging,Production">
environment-include
<environment include="Staging,Production">
environment-exclude
<environment exclude="Development">
component
<component type="typeof(ColorfulCheckbox)" render-mode="ServerPrerendered" param-Size="14" param-Color="@("blue")" />
asp-append-version
<img src="~/images/asplogo.png" asp-append-version="true">
asp-antiforgery
<form asp-controller="Home" asp-action="Index" asp-antiforgery="true" asp-route-returnurl="@ViewData["ReturnUrl"]" >
asp-for, asp-items
<select asp-for="Country" asp-items="Model.Countries"></select>
asp-for
<input asp-for="<Expression Name>">
asp-validation-for
<span asp-validation-for="Email"></span>
asp-antiforgery
<form asp-controller="Home" asp-action="Index" asp-antiforgery="true" >
Html.ValidationMessageFor
<span asp-validation-for="Email"></span>
ValidationSummary.All/ModelOnly/None
<div asp-validation-summary="ModelOnly"></div>


Some this tags we can directly use in our Blazor program, for example validation tags:



16. NET Core Project service (with controller, without controller) and global reference, by timer. Call Server API from Blazor frontend.

As in each NET Core projects in Blazor we can create service to provide needed data for site.


We can use service in NET CORE by three way - With MVC controller, without MVC controller and simple define any service as global variable in Program (RND in third project). You can see this three way in three my project templates:


We can use any service by timer - with simple system timer and Quartz service.


We can perform server API from Blazor project in different way - manually with definition HttpClient (as service or global reference in Program). And we can create list of server's API by SwaggerUI (this is example how to do this):

And than build by NSwagStudio separate layer to call Server API.


17. DataAcess in Blazor.

You can add to Blazor apps EF Core data access with various DB engine. Usually I use InMemoryDatabase - look more details in this page - How Linux Net Core 3.1 daemon (in VB.NET) can read/write data from/to ancient MS SQL 2005 and usually I use MySQL.

Right way to add EF Code with this database you can see in two my projects.


With Entity Framework we have two main pattern to accessing data. Firstly, if we working in concrete table context, in this case we usually use Linq. To working with dynamic LINQ Query usually exist a convenient way to create special extension. I show this way in my BlazorCRUD demo project.

And second choice (usually without concrete table context) - raw SQL statement. This way I show in BlazorDbBackup project (second screen from my real admin panel). In this page I has been read list on project tables.

In next page I read metadata from EF (fields description) and than show all rows.

Microsoft has no full support Database First in EF, this is big trouble from MS, because EF Code first is possible only with brand new project. But is you really working with full new projects? 99% of job is rebulding and modification existing project, in this case always need to apply Database first approach. Unfortunately MS do not admit this simple truth and continue promote CodeFirst technology. How to use Database Firts approach you can see in my page Transform Database from MsSQL to MySQL (Net Core EF DbFirst, Scaffold-DbContext, Read Db Schema, Move Users and data, EF SQL trace).

18. User Identity in Blazor.

For accounting user Blazor perform ordinary NET Core classes Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityDbContext and classes derived from this class ApplicationDbContext:



But a lot of ordinary Net Core classes working with User Identity (like HttpContextAccessor, SignInManager<ApplicationUser>) is not working correctly in Blazor. Only classes with database (like UserManager<ApplicationUser>) still working in Blazor as in Net Core MVC.

Because Blazor use SignalR connection instead simple WebRequest/WebResponse, User Authentication is not similar to previous WebTechnology. There are two different methods of AU - with break existing socket connection and reestablishing it again with cookies with login after login will be processing by simple webRequest.



First method I have published in this project template:

And second method is use IdentityServer and JWT OWIN Token.

19. Additional NET Core attributes for standard HTML5-tags.

At the moment we have a lot of HTML-tags, but NET Core provide huge number of additional attributes. For example, HTML5 standard describe 25 attributes of HTML5-Button element: accesskey, autofocus, class, contenteditable, data-*, dir, disabled, draggable, form, formaction, formenctype, formmethod, formnovalidate, formtarget, hidden, id, lang, name, spellcheck, style, tabindex, title, translate, type, value.

But Blazor support 14 additional tags for the same HTML-Button element:

  • contextmenu
  • dropzone
  • inert
  • itemid
  • itemprop
  • itemref
  • itemscope
  • itemtype
  • prefix
  • property
  • resource
  • role
  • typeof
  • uiactions
  • vocab

And, of cource, we can define own CSS attributes - this is common CSS future, for example in this project I define custom CSS to create tooltip.

20. Additional MS library for Blazor.

Blazor is Net Core application, as each of NET Core application Blazor app has a lot builting internal services:



This three library usually mandatory to each Blazor project:

  • Microsoft.AspNetCore.Components.NavigationManager
  • System.Net.WebClient
  • Microsoft.EntityFrameworkCore

And you can see in Nuget a lot of various MS library and millions and millions of various third party libraries, each of those can be add to own project. For example for one my Blazor project I has been created this library:

21. Blazor Desktop.

Greatest library from MS is Microsoft.AspNetCore.Components.Desktop, it's MS clone of old Adobe idea to start Flex on Desktop (AIR application),this is my liked type of projects and I was create a lot of various AIR application, this is colorful and awesome alternatives for bored Windows Forms apps.

Fortunately Blazor application also is possible to start as desktop application with minimal changes.


22. Third-party UI components and extension for Blazor.

Microsoft provide only couple of poor component for Blazor.

  • <LayoutView ChildContent= Layout= />
  • <RouteData DefaultLayout= RouteData= />
  • <RouteView DefaultLayout= RouteData= />
  • <NavLink ActiveClass= AdditionalAttributes= ChildContent= Match= />

Its not seriously at all. Need to provide at least the same components that was in ASP.NET in 2002 year GridView, DataList and 50+ was present in MS AJAX package for Classic ASP.NET in 2005 year. Therefore other company can be created various useful to programmer components, for example look to this packages Radzen Blazor Components containes 40+ free components, Blazorise is a good package too.


Also other companies and peoples create various list of useful projects, for example look to this list Blazor Open Source Projects and Awesome Blazor.


Blazor extension Extensions, usually adding additional JavaScript like this Logging Extensions

Not all extension is great and usefull, for example this Logging Extensions is stupid and inexplicable for me, it can be replaced only one line of Javascript code. If you download my own Blazor project template, you will see only one line Javascript I replace this extension.


But there are a lot of very useful and sophisticated extension, in fact this is interop wrapper around sophisticated and complex JavaScrip framework, look for example to this extension:

23. What missing in Blazor?

In Blazor is missing some main components and future:

  • VB.NET support - Why Microsoft vilified Visual Basic ?. C# syntax was born in 1978 year and VB was been develop as improvement stupid C syntax, for delete most stupid C ideas, for example named full different conception like Inheritance and Implementation by the same character ":" or use the same character "+" to concatenate string, accumulate digital value and even adding events to class. Is this ancient trash a really language for modern programming or this is only insult of human mind? Or this is Microsoft policies for reducing programing performance and increase price of software?
  • Designer like designer in Classic ASP.NET is absent in modern version of Visual Studio. Designer is not browser for only showing Html-markup, Designer give programmer main tools for RAPID creating sites, Designer is enter to bunch of tools, for example by click on HTML-elements EventHandler was been created automatically with all closures.
  • Blazor contains only four simplest builting components, there are nothing convenient to ASP.NET Classic components like GridView, DataList and so on. Even Combobox need to build manually by select/options tags. Is this really after 20 year of automatically generated any complex html-structure in Classic ASP.NET?
  • Classic ASP.NET contains Visual studio tools and engine to allow us place to any page <SQLDataSource> object, we always can modify one page separately from all project by simplest and fastest way - define addition SQL request directly in HTML even often without any code modification. Any programmer's conception like binding DataSource set DataMember and automatically generate Combobox or Grid also is absent in Blazor. Who has develop Blazor at all? Child, who know nothing about direction and evolution web technology last 20 year? Or Blazor is only fast, incomplete and unfinished demo project?
  • Convenient documentation and examples is absent in Blazor too. Main workable classes (like RenderFragment), all methods is not documented at all, even by one line description for IntelliSense.
  • Dependency Injection allow framework developers constantly expand and extend any functionality to infinity. Blazor functionality not assembled in one library, even base function like accessing to HttpContext need to install additional and additional library. But how customer must be know what exactly library contains needed function at all? Nuget site has no function to search symbol across all libraries. For example how can I know that even accessing to HttpContext need to select exactly Microsoft.AspNetCore.Http.Features among millions of library with similar names? Additionally to this difficulties Microsoft made a trash with Net Framework names - Net Core, Net Standard and so on. And even I have installed needed library, as you can see above in section HttpContext, Visual Studio continue showing error. It will be disappear only after project execution. What is the trash? Any previous ASP.NET technology, especially Classic ASP.NET, was working without similar troubles.
  • jQuery support and integration is absent. jQuery was be supported perfectly in Classic ASP.NET and then MS leave to support most of main tools for programmers, of course including jQuery.
  • Database First is main working case in practice, since 2008 in all ASP.NET Classic programmers used Linq-to-SQL tools and framework to allow receive in code all database objects by one mouse click. If database structure has been changed we modify code presentation of Database by one mouse click - Refresh. Instead this useful and convenient future MS propose us idiotic workflow with command line utilities what working incorrectly at all, don't understand View layer of SQL server and so on.
  • Most main Visual Studio tools like Object Browser lost their functionality in new Visual Studio, for example if I was not remember class of needed function I was always use Object Browser for searching, now it impossible. Even Find and Replace tool working with trouble if you set Project scope.
  • In each previously ASP.NET technology we can simple changing source code (including with Debugger) then simple press refresh in Browser and code was been recompiled and changing in background. After few seconds we was have new code in Browser and library. But in Blazor this development workflow is not possible now. If we want to change something, we must stop debugger, stop IIS, stop Browser. Make change and then restart application. This permanently restarting set of application slow down development process at millions times.

  • Visual Studio 2019 working at millions time slowly than VB6 environment and thousand times slowly than Visual Studio 2002-2003. Even in 486 processor with 256 MB memory VB6 studio working faster than in Core I7 with 8 GB memory. Sometimes in my brand new computer I waiting Visual Studio 2019 a couple of seconds for simplest operation like copy-past. Intellisense and variable recognizing became working unacceptably slow. Even in 486 variable recognizing was working instantly, without the slightest delay, we usually define all VB6 variable with first capital letter and always type variable with small first letter, if variable has been recognized first letter immediately appear as big and capital, it was working instantly even before Pentium processor was born. Now I see dump message with errors for 10 second and more while variables will be recognized.

As a result, this restriction of ASP.NET Core Blazor technology give programmers only tiny percents of performance ASP.NET Classic programmers, in ASP.NET Core Blazor you will create for months the same site as Classic ASP.NET programmer could created during one day, but this obscure is full fit to Microsoft point of view - price of any software in the world must be increase, so that can be induce increase cost of Microsoft stock as software leader company.





<00>  <01>  <02>  <03>  <04>  <05>  <06>  <07>  <08>  <09>  <10>  <11>  <12>  <13>  <14>  <15>  <16>  <17>  <18>  <19
<SITEMAP>  <MVC>  <ASP>  <NET>  <DATA>  <KIOSK>  <FLEX>  <SQL>  <NOTES>  <LINUX>  <MONO>  <FREEWARE>  <DOCS>  <ENG>  <MAIL ME>  <ABOUT ME>  < THANKS ME>