Blazor, Cosmos DB and OData

Blazor Icon

Decided to use some spare time to revisit Blazor. Particularly Blazor and OData working together. Taking my inspiration from Hassan Habib and his Enabling Pagination in OData post. I wanted to build upon that and modernise the approach slightly by implementing client side Blazor and bringing some of the goodies from NET5 by using a code behind approach for example.

I’ve a number of blog entries already on dealing with OData and the API aspects so this blog will focus mainly on getting to Blazor functionality

Getting Data

I’d worked on an IIS Logparser in my spare time recently that basically comprised of an SFTP client brining down my Log files and a service to process, enrich and output to a JSON file. I decided to redirect the output from JSON files to Cosmos DB.

Excerpt from the LogParser service. Simple, but does the trick.
Excerpt from LogParser service. I created a few extension methods to scrub the data from Bots etc.

There’s then some standard Cosmos DB Container setup and a method to push the log details to the DB. Again, all very straightforward.

Building out the API service and OData

Pretty much all “out of the box” implementation here. I created myself a LogController with a GET operation to hit the Cosmos DB. I intend to leverage in Redis Caching. Due to time constraints and intended usage I’ve not brought in Swashbuckle or any OpenAPI elements. Also I have to confess the GET operation is brining everything back from Cosmos. The OData implementation is fully working but on resulting IEnumerable collection of everything.

API service up and running with OData functionality

Blazor & Pagination

This is where the adventure begins really as my exposure to Blazor had been pretty limited thus far.

I began with the out of the box Blazor example and the “FetchData.razor” page and separated out the code into a partial class. NET5 now brings some nice Blazor Dev features such as bundling pages together in Visual Studio….

My code behind class is a partial class with an override method for the OnInitializedAsync. All code sections have been removed from the “front end” Razor page.

As you can see in the screenshot above I’ve created a Log Service to provide a service layer call out to the API endpoints.

Service GetAllLogs method signature.

Following Hassan Habib‘s OData pagination example I started to build my method sig out accordingly. The “cityChange” variable is described in the following section.

Data Binding and Event Firing

I wanted to bring in some of the basic UI interactions to examine how easy they are to implement in Blazor. With the one-way and two-way binding and code behinds it’s all feeling a little Silverlight but a lot slicker and maintainable.

Razor page looping through the logs.

As you can see from the above there are onclick events handled via code behind methods to deal with the pagination….

And yes I am repeating myself, and no this is not Production ready code 🙂

I then wanted to have a list of cities that I could select from a dropdown and have the event fire and OData to filter out accordingly….

GetAllCities in the LogService.

As you can see above, I’ve brought in a “ukSwitch” flag that fires on a checkbox selection to filter out on the UK logs (this should really be “GB” as that’s how they appear in the IIS Logs).

It Feels Slick

The first hit on the FetchData page is slightly slower on brining down the necessary JS elements but the whole UX does feel rather slick and not clunky. Leveraging Blazor and Odata together gives a very powerful feature rich experience with very little development effort.

Example showing UK and City filtering.

Next Steps

Sure it’s a little noisy/messy at the moment. In my mind it’s pretty impressive from what can be achieved in a few hours work. Also, it does give me a lot of possibilities next time I’m thinking about UI implementation.

Next steps would be to definitely sort the UI out and bring in an isolated CSS file. I’d also build the OData out to inject the query strings into the actual DB calls. Also introducing a layer of caching in front of that.

The Bizarre World of Crap Internet Adverts.

There seems to be a lot of crappy internet adverts about these days. Normally I scroll through them and they don’t register but recently they seem to be incredibly cheesey and a little sinister. It’s almost like having an advert of someone with a passport or driving licence is supposed to make it more trustworthy or something. Here’s a delightful section I clumped together for your enjoyment. Note that the adverts are screenshots and I’m not affiliated with any of these!

Here’s Rupert desperately clutching on to his gammon passport so he can get his will sorted.
Brian showing us his council tax bill for some reason. Also Brian will murder you if you attempt to smoke in his house.
Everyone can’t get enough of these National Insurance card masks. So cool!
Double points here for trustworthy ratings. The feckin bowler hat!! and passport
This lady has made so much cash from investing in Amazon she doesn’t even have chance to get down the bank with all the bags of money.
Here’s Bob with his driving licence. Thanks Bob. Also can I have my ball back please?
Nice one Terry. Big surprise eh? You can use the rest of the money to sort your kitchen out.
That’s not your real hand. I can’t take you serious unless you have either a passport or your driving licence. Also, no will for you
Your birth certificate awaits!

Speaking of spam. Here’s how to remove yourself from 0808 Vodafone marketing calls.

Unable to place tray back into De’Longhi Magnifica

dellonghi coffee machine

This article describes out to resolve the problem where you’re unable to place the tracy back into the De’Longhi coffee machine.

The De’Longhi Magnifica coffee machine is the best machine you can get for under £300. Been using mine daily now for over a year. However, it does develop a weird quirk from time to time.

After removing and cleaning the tray one day I was unable to place it back into the machine. Having a look at what the issue was I could see that the infuser was stuck fast and hadn’t reset itself back to it’s upright position. Annoyingly the only way you can get the infuser to reset is by the machine being able to start correctly. In order to get the machine to function correctly you need the tray in it’s correct position.

Solution

The way to resolve this problem is to trick the machine into believing the tray is back in it’s correct position. This can be achieved by simply taking the waste container out of the tray and positioning it where it would normally sit in the machine. At that point the infuser will rise back to it’s normal position and you can sit the tray back in completely.

Image showing how to place tray back into De'Longhi coffee machine.

7 Tips To Deal With Large Scale Code Refactoring

image of jigsaw pieces

A few weeks back I noticed that a part of the code that I’d been working on for over a year seemed to be growing in size and needed to be addressed in order to avoid future headaches and pain. The code is by no means monolithic but of a significant size to be a thing in it’s own right and not a quick 15 minute fix. I could see that action was needed in order to support future maintainability and scalability. Here’s 7 tips for refactoring…

1. Have Unit Test Code Coverage Before You Begin!

If you don’t have unit tests covering the existing code then why not?!. You’re simply not going to be able to confidently refactor without a high percentage of test coverage across the all important business logic. If you don’t have this in place before you begin then you have to either invest in the time now to get the unit tests in or forget it. Seriously, it’s just not worth attempting otherwise.

2. Gain Stakeholder Buy-In

Ensure that stakeholders are informed of why, what, when. Why you have to do this, what is it you’re doing and when (i.e some form of temporal data on how long the work is going to take and estimated delivery time) Agile/Scrum pointing can play a part here.

3. Break The Changes Down Into Manageable Chunks

It would be crazy/demoralizing/suicidal! to lock yourself away for a few days/weeks and holistically tackle the entire refactor. Break the work down into modular chunks by:-

  1. Identifying the components/modules by theme or functionality and start breaking them out. This can also identify potential areas of the code that could be brought out into future microservices.
  2. Remove/Exclude broken functional areas for now. Don’t be afraid to simply exclude classes, projects etc. These can be removed while you deal with 1 functional area at a time.
  3. Plan the work around functional themes/areas. This way you can address 1 change at a time and see the work items moving into “done”/”ready to test”.

4. Feedback

Depending on the size of the workload it’s worthwhile updating any stakeholders. If you’re following Scrum then you’ll already be doing this in the Stand-ups.

5. Improve

Whilst we’re “in among the weeds” of the code we can sometimes identify areas that haven’t been touched for days/weeks/months. If you see something that can be improved then don’t be afraid to tackle it if it’s a quick fix (or even better) open an improvements style Story into the backlog.

6. Deliver Small Manageable Changes

Hand in hand with Point 3 the refactoring changes should be delivered in relatively short-lived chunks. Let the Pull Requests be short and the CI/CD pipelines (and toolset) work to your advantage here.

Flowing tap

7. Rinse & Repeat

Once you’re done don’t be afraid to challenge the code and it’s architecture again. Ideally, the upfront planning and architecture should have alleviated the need to have to refactor to made the code scalable however, as a Developer getting Sprints over the line and tackling business requirements, a changing landscape/environment the code can become bloated. If you can see scalability becoming a problem or Class sizes becoming unwieldly then stand up and shout!. It’s better to tackle the issue sooner rather than later.

There were build errors. Would you like to continue and run the last successful build?

There Were Build Errors. Would You Like To Continue And Run The Last Successful Build?

Has anyone ever selected yes to the below? Surely the answer will always be “no let me sort out the crap I’ve just created?”

There Were Build Errors. Would You Like To Continue And Run The Last Successful Build?