๐ŸŒ APIโ€™s Web

back

This article describes some of the web technology choices in this software architecture.

Contents

AJAX

AJAX is a way to load part of a web page, so the whole page does not have to be refreshed. This may make the user interaction smoother, than reloading the entire page every time.

For AJAX'ing such partial web content, our team programmed wrapper functions in JavaScript, around calls to jQuery, so we could AJAX with a single code line and handle both partial loads and full reloads the same way. It saved quite a few lines of JavaScript code.

Our strategy was to prefer full loads, so we could keep most logic in the C# realm. This before resorting to AJAX calls. See Full Load โ€“ Partial Load โ€“ Cient-Native Code.

JavaScript / TypeScript

JavaScript is a programming language with a wide range of applications. Originally it was run in web browsers to optimize the user experience.

JavaScript was less preferred as an architectural choice. JavaScript's weak type system played a role. The strange behavior and trickiness in JavaScript (part due to this weak typing) gave it less appeal.

For web, other technology was preferred in this architecture: The idea behind MVC was logic on the server-side. Views were in Razor. Best to keep most logic C# was the idea.

JavaScript would easily get bloated, getting out of hand from a maintainability perspective, was the prevailing opinion. You could refactor C# code, upon which lots of the JavaScript might break unexpectedly, with an error message tucked away in some console window, instead of right in your face when compiling.

TypeScript may have saved the day to cover for the weak typing from JavaScript. But we hadnโ€™t tried that yet.

But still: logic in one place in one language (C#) felt so nice. I guess the love for C# was strong.

The idea was that a full page load was 1st choice, AJAX'ing the 2nd choice, and last in line JavaScript only to support the user interaction. No business logic. See also: Full Load โ€“ Partial Load โ€“ Cient-Native Code.

For this last-resort JavaScript we used jQuery and some home-programmed JavaScript libraries: JJ.Framework.JavaScript which had some merit, but may have been superseded by newer tech by now.

I realize JavaScript is popular with a lot of people and that this is a powerful force. I donโ€™t know how my opinion would change, if I would try a newer JavaScript version, TypeScript, newer tech and libraries. My heart says Iโ€™d rather stick with C# though.

Html.BeginCollection

In MVC it is not so straightforward to HTTP a tree structure in postdata.

JJ.Framework.Mvc makes that easier, by offering an HtmlHelper extensions: Html.BeginCollection. Using that API you can send a ViewModel with arbitrary nestings and collections over the line. It would be restored as a ViewModel at the server side.

In the View code you would wrap each nesting inside a using block:

@using (Html.BeginItem(() => Model.MyItem))
{
    using (Html.BeginCollection(() => Model.MyItem.MyCollection))
    {
        foreach (var x in Model.MyItem.MyCollection)
        {
            using (Html.BeginCollectionItem())
            {
                ...
            }
        }
    }
}

So each time you enter a level, the HtmlHelper is called again and the code wrapped in a using block.

There can be as many collections as needed, and as much nesting as you like. The nesting can even be spread around multiple partial views.

Input fields in a nested structure look as follows:

Html.TextBoxFor(x => x.MyProperty)

Or:

Html.TextBoxFor(x => Model.MyProperty)

But not like this:

Html.TextBoxFor(x => myLoopItem.MyItem.MyProperty)

Otherwise the input fields might not bind to the ViewModel. This may force you to program partial Views sometimes. That may be good practice anyway, so might not be such a big trade-off.

Html.BeginCollectionItem

In MVC it is not so apparent how to send a collection as HTTP postdata.

One alternative is the often-used Html.BeginCollectionItem:

@foreach (var child in Model.Children)
{
    using (Html.BeginCollectionItem("Children"))
    {
        ...
    }
}

This API has some limitations:

To send trees and arbitrary nestings over HTTP postdata, consider using Html.BeginCollection from JJ.Framework.Mvc.

back