Sunday, 27 January 2019

Web Assembly with C# II – Blazor Components


This post is part of a series that introduces WebAssembly with and Blazor, a web framework to build single page applications using C#, Razor and ASP.NET Core. If you would like to see the previous posts, please follow the below links. You can also follow the GitHub repository created for this series here.
Part I - WebAssembly with C# – Introduction to Blazor

In this post let’s begin by looking at the project we created and we’ll look more closely to the Counter component (Pages/Counter.cshtml) to better understand the Blazor components features and how to build, use and share them not only on a single project but across multiple projects.

Routing


The first line contains a @page directive. This is used to define the routing of the component. After compilation the generated classes are decorated with a RouteAttribute with the specified template and the runtime looks for those attributes when deciding which components should be rendered.

Multiple route templates can be defined, so it would be possible to add another page directive such as @page “/anothercounter”. From that point on the component would respond for requests either for /counter and /anothercounter. Please check this commit to see how you could define the new route template and use it on the navigation menu of the application.

Its also possible to pass arguments so we could define a @page “/counter/{currentCount}” and use that argument to set, for example, the initial value of the counter. Optional arguments are not allowed so multiple routes must be defined.

Razor template


The middle part of the component should be very familiar to anyone that has come across with the Razor syntax in the past. If you’re not familiar with Razor I recommend you to give a read of the syntax reference that you can find on this link before continuing to read this and the following posts.

@functions block


The last part of the Counter component is the @functions block, where all the members (methods, properties, etc.) of the component call are defined so that they can be used for component logic and event handling.

In this component we have a field currentCount that is used to maintain state and a method IncrementCount that is used when handling the onclick event of the button defined in the DOM. This way when the user clicks the button the IncrementCount method is called, the component regenerates its render tree and Blazor applies any modifications to the DOM by comparing the new tree with the previous one, which makes the displayed count to be updated.

Components parameters and reutilization


Now that we saw the counter component in detail let’s suppose that we wanted to use it inside another component. When compiled a C# class is generated and its name matches the name of the component we created so if we wanted to include the Counter component defined in Counter.cshtml file on the Index component all we have to do is adding the following markup to the Index.cshtml file:

<Counter />


If you start the application you’ll notice that the Counter component is now displayed on the Index component as expected. In this case we can now call the Index component the parent component and Counter is its child component.

On the parent component markup we could also pass parameters to a child component or provide some content that should be rendered by it by placing it inside the child component tags, for example:

<Counter Title=”Index Counter”>
This counter is being displayed on the Index component.

</Counter>

For this to work some changes need to be made to the Counter component, obviously.
  • First we have be declare two private properties (one named Title of type string and another named ChildContent of type RenderFragment) both decorated with the [Parameter] attribute; 
  • Secondly we then use Razor to display the Title and the ChildContent properties on the component markup;
  • Lastly, since this component is also being called directly from the navigation menu, we’ll set a default value for the Title so that it can be displayed when no Title is given. All of these changes can be seen on this commit.

Restart the application and you’ll notice the new Title and Child Content being rendered on the Counter component inside the Index component. If you click on the Counter link of the navigation menu, you’ll also see the default title value being applied.

Internals

To better understand everything that was said above lets look at the generated DLL after compilation with Visual Studio. The generated code can be seen in the below picture:


Please note some of the things we already discussed above and see how exactly the Razor markup that is defined in the .cshtml is taken and converted into the implementation of the overriden BuildRenderTree method.

Sharing components


As previously stated Blazor components can be shared across multiple projects. For that we need to create a Blazor library and add a reference to it in our current solution. Executing the following commands in our solution folder will do exactly that.

dotnet new blazorlib -o WasmWithBlazorComponentsLib
dotnet sln add .\WasmWithBlazorComponentsLib


Reloading the solution in Visual Studio will show the new project. The Blazor Library template already comes with a default component and we'll now add it to our Index component so it can be rendered in the main page.

First we'll add a reference of the newly created library to the main project (Right click on the main project > Add > Reference). Now we'll need to add the following directive Pages/_ViewImports.cshtml:

@addTagHelper  WasmWithBlazorComponentsLib.Component1, WasmWithBlazorComponentsLib

There are a couple of things that I would like to clarify at this point:
  1. The reason we add the above directive to the ViewImports file is so that the component can be used in all pages that have this file as their base layout, which is something that is happening in all the components of our application. If we are sure we just need to use it in a single component, we could add the directive in the corresponding file instead;
  2. As you can notice the @addTagHelper directive format is <namespace>.<component name>, <assembly name>. However, if the assembly has multiple components and we would like to include all of them, then the wildcard * could be used instead, such as <namespace>.<component name>, <assembly name>.
Finally, similar to what we did with the Counter component, we can now add the tag <Component1 /> to the Index component so that it will be rendered on the main page. We can verify this by running the application after all changes are made. All these steps can be seen on this commit.

Wrapping up for today


As you can see creating, reusing and sharing Blazor components is very easy and the programming models are very similar to everyone that is familiar with modern .NET web application development.

There is a lot more that can be said about Blazor components and we'll surely discuss that in the next posts.


Wednesday, 9 January 2019

WebAssembly with C# – Introduction to Blazor

To better start this year I’ve decided to start learning more about WebAssembly and, because I do mostly work with .NET technologies nowadays, starting out with Blazor was an obvious choice.

WebAssembly, for those who are unfamiliar with it, is a open web standard supported out-of-the-box in modern browsers. Is a bytecode format optimized for performance.

Blazor, on the other hand, is a .NET web framework that runs in the browser with WebAssembly. This is possible because a Blazor app compiles all the C# and Razor files into .NET assemblies that are downloaded to the browser, together with the .NET runtime. Blazor then uses JavaScript to bootstrap the .NET runtime that will load all the needed references. JavaScript interoperability also allows for DOM manipulation and direct access to browser API calls.

There’s a lot more that can be said about all the above points but for now, and before starting to dig into code, I think its also necessary to be aware that Blazor apps are built with components, which is nothing more than a piece of UI that can be nested, reused and shared between different projects. Examples of components can be a form, a dialog or even a full page.

We’ll understand even more of all this as we go along. For now lets make sure we have everything we need to start coding.

Environment Setup


In order to be able to create Blazor apps, your system must met the following requirements:
dotnet new -i Microsoft.AspNetCore.Blazor.Templates 

Create your first Blazor project


To create a new Blazor application you can use the dotnet command line or Visual Studio. I’m a huge fan of using the dotnet CLI to better organize my solutions (maybe more on that on a future post) but for now I’ll keep it simple and I’ll choose the later.

After installing the above requirements, creating a new Blazor project is the same as creating other ASP.NET Core Web Application:

  • Select File > New Project > Web > ASP.NET Core Web Application;
  • Be sure to choose .NET Core and ASP.NET Core 2.1;
  • At this point you’ll have three different Blazor options to choose from. We’ll select the first one ‘Blazor’ for now and later I’ll expand more insight about the other options. Click OK.

When finished, you’ll have a project containing some Razor pages, some typical ASP.NET Core code that bootstraps the application and a wwwroot folder containing the index HTML page along with some CSS and other files. Select Debug > Start Without Debugging (or CTRL+F5) and the browser will open and show you the default Blazor application.

Calling it a day


This was just a quick intro on what Blazor and WebAssembly are and what you need to prepare a development environment for creating Blazor applications and how to use Visual Studio to do so.

Next post we’ll look more deeply into Blazor components and layouts.

See you on the next post.

Tuesday, 4 December 2018

Remote Debug of a Windows Server Core hosted application from VS 2017

If you have an application hosted in a Windows Server 2016 Core machine and would like to debug it directly from Visual Studio 2017, then its very simple to configure remote debugging.

First, you must download the Visual Studio Remote tools from this link. Save it somewhere on the machine disk, for example "C:\temp\vs_remotetools.exe".

Next, using the command-line as an administrator, invoke the following command:

C:\temp\vs_remotetools.exe /install /quiet


This will silently install the remote tools. Usually, I like to have the tools running as a service so I don't have to start those each time. This is very convenient specially for development environments.

Go to "C:\Program Files\Microsoft Visual Studio 15.0\Common7\IDE" and execute rdbgwiz.exe. Despite being a no-GUI edition, there are some applications that do show some user interface and fortunately this is one of those.

Click next and on the second screen be sure to select "Run the Visual Studio 2017 Remote Debugger service". You can then enter the credentials to use when running the service or you can leave the default "LocalSystem" account, if you prefer. After clicking next you'll have the change to select the type of networks to use for debugging and if all goes well you'll have a message on the last screen saying the service was configured correctly.

To ensure the service is running execute the following using PowerShell:

Get-Service -Name msvsmon150


Now that the remote is up and running, open your project with Visual Studio 2017, set the breakpoints you need and open the "Attach to Process" dialog (Debug > Attach to Process). Input the IP of the machine where you just installed the remote debugger and use port 4022 which is the default. After that click on Refresh and you should see the list of processes running on that machine, like the below figure:


Final step, as you may know, just select the process you want and click on Attach. Execute any necessary steps and the debugger should now stop in the breakpoints you've setup.

If you'd like to run the debugger tools "on-demand" instead of running as a service, then you can run msvsmon.exe each time that's needed, which by default will be located under "C:\Program Files\Microsoft Visual Studio 15.0\Common7\IDE\Remote Debugger\x64".

Hope this is useful to you. Feel free to comment. See you on a next post.

Thursday, 27 September 2018

Configuring custom endpoint for Azure Service Fabric applications

When creating clusters in Azure Service Fabric, one of the options you have when configuring the node types is to define the custom endpoints needed for your Service Fabric applications.



However, after creating the cluster, if you go back to the node type details you'll notice that there's no option to allow you to customize the endpoints, either by adding new ones or removing the ones configured initially when creating the cluster.



I've done some searching and found out that there are some people out there that didn't find out a solution for this and come up with various workarounds, one of them was to delete everything and recreate the cluster from scratch! That is never a good option obviously.

Let's try to avoid that kind of solutions and please notice that when you create a cluster one of the resources that gets configured is a load balancer. Is in that resource that you can configure the custom endpoint ports needed to reach your services from the outside world.

Go to the load balancer configuration and open the health probes section. In there you need to add a new health probe configured to the port you need for your endpoint, in this case 21000.


When Azure finishes the creation of the Health probe, you can go to the Load Balancing Rules section and create a new rule that will use that Health Probe and is configured to the same port, such as the example below.


And that's it. Your service is now exposed to the outside world via the chosen port.

Happy coding.


Thursday, 28 June 2018

Upgrading XRDP in Ubuntu 16.04

In the past week we were having some issues at work while trying to connect to some Ubuntu servers via RDP. Since we have Windows laptops, it’s very common for us to use this protocol to connect remotely to our linux machines so we always install XRDP on those servers every time we need to have a remote connection to a graphical interface.

Unfortunately the XRDP version that you can get from the standard apt-get command in Ubuntu 16.04 is really outdated and that causes the following to happen:
  • Crashes on some applications that require more graphical capabilities such as the Robot Operating System (ROS). In this case the graphical interfaces only worked if we were connecting directly to the virtual machine but not via XRDP;
  • Protocol errors when trying to RDP into the machines using the Microsoft Remote Desktop app that we have installed on our Surface Hub (yes, we have acquired one of those and it’s simply awesome!)
After some research we decided to find a way to update the XRDP package but we really didn’t want to go with all the trouble of getting the source code from the XRDP Github repo and compiling it ourselves. So our approach to solve this was to add a PPA to our machines and in this case we used one from hermlnx. So upgrade XRDP we just had to perform the following commands with sudo privileges:

sudo add-apt
sudo apt-get update
sudo apt-get upgrade xrdp


After the upgrade, all the above issues were gone and we noticed some other improvements, such as:
  • Everytime we now reconnect to those machines via XRDP, it recovers the already existing session instead of creating a new one, something that happened with the previous version. It was possible to workaround that but it required to change some XRDP settings and to remember the port used everytime we established a session so that we could use the same port when reconnecting;
  • The keyboard layout (we use en-GB here) is now automatically recognized instead of defaulting to en-US. There is also workarounds for that with the previous XRDP versions, but it required a lot of commands and tweaks on the XRDP keyboard maps.
So if you’re having the same issues, or even others, when establishing RDP connections to Ubuntu 16.04, I trully recommend to update XRDP before anything else. I’m certain that will help you a lot!

See you on the next post.

Monday, 22 January 2018

Installing Pentaho CE 8.0 with PostgreSQL on Ubuntu Server 16.04 LTS

Last week I had to install a Pentaho CE 8.0 instance on a Linux virtual machine. Ubuntu was the chosen distro and for many reasons I like to keep it simple, so instead of installing the desktop version I made the decision to run the software I needed on top of Ubuntu Server 16.04 LTS. Being the first time I had to install Pentaho CE I looked for articles to guide me through the process but unfortunately most of them were out-dated or using graphical interfaces that I didn’t had and didn’t want to add, otherwise I wouldn’t have chosen to go with the Ubuntu server version in the first place.

This post is the compilation of all the steps I had to perform to install the needed software. The steps below don’t cover the installation of the Ubuntu server distro itself, so its expected that you already have a (virtual) machine with the Ubuntu Server installed. Please also take in mind that I’ll be using almost all default passwords and configurations to keep this post the simplest as possible.
  1. Before we start
  2. Install Java Runtime 8
  3. Getting Pentaho Server 8.0 CE
  4. PostgreSQL installation
  5. Configuring Pentaho connection to PostgreSQL
  6. Running Pentaho Server

Before we start


# Update the apt-get index

sudo apt-get update

# If you are running a clean Ubuntu install I also recommend to upgrade the system

sudo apt-get upgrade

# Since we'll later need to unzip some files let's also install the unzip package.

sudo apt-get install unzip

Install Java Runtime 8


# This command will install the Java JRE package, specifically the OpenJDK 8

sudo apt-get install default-jre

# Next we need to set the JAVA_HOME environment variable, but before that we need to check where exactly Java is installed


sudo update-alternatives --config java

# Copy the Java installation path use an editor to open change the environment variables

sudo vim /etc/environment

# At the end of the file add the following line, making sure to replace the path with the one you copied above

JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64"

# Save the file and reload it. After that you can check if the environment variable is properly configured with a simple echo command

source /etc/environment
echo $JAVA_HOME

Getting Pentaho Server 8.0 CE


# Download the package using wget. Please take in mind that the name of the file is the most recent at the time of this writing. You can double check the correct link on sourceforge (https://sourceforge.net/projects/pentaho/files/).
wget https://sourceforge.net/projects/pentaho/files/Pentaho%208.0/server/pentaho-server-ce-8.0.0.0-28.zip/download -O pentaho-server-ce-8.0.0.0-28.zip

# When the download is completed we need to unzip the file and move the extracted pentaho-server directory to another directory. In this example I'll just put everything under /opt/pentaho

unzip pentaho-server-ce-8.0.0.0-28.zip
sudo mkdir /opt/pentaho
sudo pentaho-server /opt/pentaho

# Next we'll create a pentaho group and user on the machine and configure it to be the owner of the /opt/pentaho path

sudo addgroup pentaho
sudo adduser --system --ingroup pentaho --disabled-login pentaho
sudo chown -R pentaho:pentaho /opt/pentaho

PostgreSQL installation


# It is time to install the PostgreSQL instance. Once again we'll just use apt-get to install the required package
sudo apt-get install postgresql

# By default a postgres user will be created, without any password. So next step is to set the password for this user
# The following commands will open psql with postgres user, set its password and quit psql

sudo -u postgres psql postgres
\password
\q

# Now that we have a password set for the default user, we need to open the pg_hba.conf file using an editor and allow local connections.

sudo vim /etc/postgresql/9.5/main/pg_hba.conf

# Locate the line that looks like:

local all all peer

# Replace the peer method to md5, save and close the file and restart postgresql
sudo service postgresql restart

Configuring Pentaho connection to PostgreSQL


# Almost there but first we'll need to run some SQL scripts to create some needed databases on the PostgreSQL instance.

cd /opt/pentaho/pentaho-server/data/postgresql
psql -U postgres -h 127.0.0.1 -p 5432 -f create_jcr_postgresql.sql
psql -U postgres -h 127.0.0.1 -p 5432 -f create_quartz_postgresql.sql
psql -U postgres -h 127.0.0.1 -p 5432 -f create_repository_postgresql.sql

# Next we'll configure JDBC to use PostgreSQL

cd /opt/pentaho/pentaho-server/tomcat/webapps/pentaho/META-INF
sudo vim context.xml

# On both of the Resources configured in that XML file make sure to alter the driverClassName and url attributes so that your final result will look something like

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/pentaho" docbase="webapps/pentaho/">
   <Resource name="jdbc/Hibernate" auth="Container" type="javax.sql.DataSource"
     factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" maxActive="20" minIdle="0"
     maxIdle="5" initialSize="0" maxWait="10000" username="hibuser" password="password"
     driverClassName="org.postgresql.Driver"
     url="jdbc:postgresql://127.0.0.1:5432/hibernate" validationQuery="select count(*) FROM INFORMATION_SCHEMA.SYSTEM_SEQUENCES" />
   <Resource name="jdbc/Quartz" auth="Container" type="javax.sql.DataSource"
     factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" maxActive="20" minIdle="0"
     maxIdle="5" initialSize="0" maxWait="10000" username="pentaho_user"
     password="password" driverClassName="org.postgresql.Driver"
     url="jdbc:postgresql://127.0.0.1:5432/quartz" validationQuery="select count(*) from INFORMATION_SCHEMA.SYSTEM_SEQUENCES" />
</Context>

Running Pentaho Server


# Start the Pentaho Server 8.0
cd /opt/pentaho/pentaho-server
sudo ./start-pentaho.sh

# If needed use ifconfig to find out your current IP address
ifconfig


On another machine just open a web browser and hit the 8080 port of the machine were Pentaho Server is running. If everything went as expected you should see the below screen.



Enjoy and see you on a next post.

Wednesday, 13 December 2017

Styling RadAutoCompleteTextView with Nativescript and Angular2

Lately I’ve been working a lot with Nativescript to develop mobile apps able to run in Android and iOS devices.

One of the apps that I just finished required me to use the nativescript-pro-ui controls, which proven themselves to be quite useful for sure. In this particular case I had to use the AutoComplete control. Everything was going ok until the moment I had to apply some styling to that control using CSS.

As expected I created a class in my stylesheet and applied it to the RadAutoCompleteTextView but unfortunately that wasn’t enough. Some of the properties such as the border color and width were applied correctly but for some reason font size and font face were just being ignored. After some research I found an opened issue on their Github repo and found out someone else with a similar problem. The presented workaround seemed to be using Nativescript Core instead of Angular2 so I just tried to do something similar.

Once again I had to face the fact that developing in frameworks such as NativeScript, Xamarin and others still require you to understand how Android and iOS native code works, otherwise you’ll have a real hard time trying to figure out how you can apply some transformations to the native controls that are generated when the app is running.

Below are some code snippets that worked like a charm. I think the code speaks for itself but in those I’m basically getting the references to the native controls on each platform and setting up the font face and the padding of the text field control that RadAutoCompleteTextView generates.

home.component.html

<RadAutoCompleteTextView [items]="customersList" class="form-input" hint="Search" suggestMode="Suggest" displayMode="Plain" (didAutoComplete)="onCustomerSelected($event)" (loaded)="onAutoCompleteLoad($event)">
    <SuggestionView tkAutoCompleteSuggestionView>
        <ng-template tkSuggestionItemTemplate let-customer="item">
            <StackLayout orientation="vertical" class="picker-entry">
                <Label [text]="customer.text"></Label>
            </StackLayout>
        </ng-template>
    </SuggestionView>
</RadAutoCompleteTextView>


home.component.ts

import { TokenModel, AutoCompleteEventData, RadAutoCompleteTextView } from "nativescript-pro-ui/autocomplete";

// (...)

public onAutoCompleteLoad(args: AutoCompleteEventData) {
    var autocomplete = args.object;

    if (isAndroid) {
        let rad = autocomplete.android;
        let nativeEditText = rad.getTextField();
        let currentApp = fs.knownFolders.currentApp();
        let fontPath = currentApp.path + "/fonts/futurat.ttf";

        nativeEditText.setTextSize(14);
        nativeEditText.setTypeface(android.graphics.Typeface.createFromFile(fontPath));
        nativeEditText.setPadding(7, 16, 7, 16);
     } else if (isIOS) {
        let rad = autocomplete.ios;
        let nativeEditText: UITextField = rad.textField;

        nativeEditText.font = UIFont.fontWithNameSize("FuturaT", 14);
        nativeEditText.leftView = new UIView({ frame: CGRectMake(7,16,7,16) });
        nativeEditText.leftViewMode = UITextFieldViewMode.Always;
     }
}


Happy coding and see you on a next post!