Including TinyMCE in an ASP.NET Project

Tags

, , , ,

Depending on whether the user is logged into the application, either an editor or a div containing the data will be displayed. The editor appears like this, during an authenticated session:

Visual Studio’s Solution Explorer lists the available plugins for TinyMCE under /tinymce/plugins. All the options in the following code are included with the free version of TinyMCE.


tinymce.init({
selector: '.test',
plugins: 'table, lists, link',
toolbar: 'table, numlist, bullist, link',
menubar: false,
statusbar: false
});

Adding plugins to the toolbar causes all the default buttons to disappear, as TinyMCE reverts to this if nothing is specified in the init(). Everything must therefore be specified, so the options would be:


plugins: 'table, lists, link',
toolbar: 'undo, redo, styleselect, bold, italic, alignleft, aligncenter, alignright, alignjustify, table, numlist, bullist, indent, outdent, link',

The application needed a tabbed UI that enables switching between the three data fields. Here I have a separate instance of TinyMCE for each tab pane. Initially the tab buttons weren’t showing, so I’ve used Bootstrap.css buttons, and added margin-right‘ attribute to two of them for spacing.

The initial code for the tab content included LINQ statements to fetch in-memory data, and creates an instance of TinyMCE for each pane.

For cases in which you don’t want the user to modify the data using the editor, it’s possible to use
tinymce.activeEditor.setMode(‘readonly’), but it’s more efficient to simply replace the tinymce() call with a div containing a Razor helper to fetch the decoded content from the model.

View-Based Authorisation

If the user doesn’t have permission to modify the data, the ‘Save’ button shouldn’t be displayed. This is a simple matter of adding an ‘if’ statement in the view.


@if (sessionStatus != null && sessionStatus.HasRole("Editor"))
{
Save
}
Close

The above uses our own in-house authentication service, but ASP.NET Core has a native feature that’s similar:


@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService AuthorizationService

@if ((await AuthorizationService.AuthorizeAsync(User, "PolicyName")).Succeeded)
{

You are authorized.
}
else
{

Go away!

}

Passing Data from TinyMCE to the Entity Framework Model

At first the application refused to save modifications made in the TinyMCE editor. I put a breakpoint at the line:
return Json(new { success = model.Put(_uow), errors = model.errors });

And got the following errors:
'System.Data.Entity.Infrastructure.DbUpdateException' in EntityFramework.dll
and
A potentially dangerous Request.Form value was detected […]

The problem is the model really doesn’t like to accept data posted back as HTML. We have to disable input validation to allow this. For simple projects, we can add the [AllowHtml] attribute to whichever model properties represent data entered in the TinyMCE editor, e.g.


[AllowHtml]
public string ItemDescription { get; set; }

[AllowHtml]
public string ItemSummary [ get; set; }

Apparently, the recommended way is to disable validation at the controller, by giving it the following attributes:

[HttpPost]
[ValidateInput(False)]

I’m not sure why the latter is recommended over the former. As you can probably see, the model attribute is more specific in allowing only HTML for selected items, whereas the controller attribute disables validation entirely for whatever is posted back.

Advertisements

Why Ireland’s Repeal of the 8th Amendment Might Not Be Such a Bad Thing

Tags

, , , , ,

[Reposted from my other blog]

While both the pro-choice and pro-life campaigners clearly frame the abortion issue in entirely different terms, the salient question, though the debate leading up to the referendum was deflected from this, was whether the freedom of the individual outweighs the unborns’ right to life. More specifically, on what basis could we argue objectively that both have an equal right to life, as the 8th Amendment of Ireland’s Constitution asserts?

I don’t think many of us are opposed to abortion because of religious dogma, though we could argue that any constitution that appeals to the sanctity of life must invoke something transcendent and absolute, a ‘necessary being‘, to put it in Catholic terminology, to place it above the consensus of lawmakers and politicians, and above utilitarian thinking. We claim that man is created in the image of God, and it’s upon that concept that the sanctity and dignity of human life are predicated, and in turn human rights and social justice. Therefore, one person’s freedom is secondary to another person’s right to life. The more society devalues human life to justify a societal demand, and the lives of the unborn sacrificed to consumerism and individualism, the more our convictions about human rights and social justice become subject to question.
The effects of this are already maniftested in our politics. Society today seems bitterly divided between conservative populism and the pseudo-liberal manipulations of George Soros billionaire lobbyists. Both exploit prevalent individualism and our base instincts, while the lobbyists’ demands for society are marketed as ‘progressive’ causes – I think that’s descriptive of the recent pro-choice campaign.

So, yes, I am firmly and unapologetically pro-life, though I still wonder if the 8th Amendment should have existed in the first place. A constitution should generally prohibit the state from violating its citizens’ fundamental rights, and the unborns’ right to life is already implicit in the wording and spirit of Ireland’s Constitutition. The 8th Amendment, conversely, seems intended to pre-empt conscience, reason, judgement and case law, which is just about the worst way of approaching situations that aren’t black and white. Secondly, one only needs to look up the Pro-Life Amendment Campaign’s background on Wikipedia to see the campaign for that was established by a number of overtly religious organisations with a decidedly exclusive membership. Effectively it was lobbying by a minority to enforce religious beliefs on a society, regardless of whether the public opted for that.

The execution and outcome of last week’s referendum saddens me for another reason. There was a time when it was deemed progressive to campaign for the right to life and human dignity, while speaking truth to power. We had a political left that campaigned on things that really mattered – the arms trade, homelessness, oppressive regimes, animal cruelty, etc. We wanted the social justice that Martin Luther King dreamed of, not the vicious identity politics and race baiting that today passes for ‘left-wing’ opinion, or peurile campaigns to affirm our base mentality. For a while it seemed humanity could aspire to a world in which everyone had a decent quality of life, that collectively we could do something (though I wasn’t sure exactly what) about the scenes of war, famine and poverty that were shown on our televisions.

Reasons for Optimism

What next? The referendum heralded the decline of the Church’s authority in Ireland, and a change in the society’s values. Roughly 60% of the voters opted for the repeal, and ~30% voted against it despite a strong campaign to preserve the Amendment. This ~30% is roughly the same percentage of the population who attend Mass regularly, and it has been in decline since the 1970s. Despite this, I really think some good will come of this situation.

History is replete with examples of what happens when the separation between Church and state is violated, when religious authorities think they’re above the law and when state authorities attempt to override individual conscience. Among these, we know, is the institutional cover-up of child abuse within the Church hierarchy, which I reckon was enabled by the power and the lack of accountability that priesthood offered. We can also look at churches that became irrelevant by trying to become acceptable to the secular world.

The Church has gone from being part of the establishment to being counter-cultural. No longer is Catholicism a tradition that people blindly conform to, but an engaging faith that must survive by changing hearts and minds. It’s up to the saintly to rebuild the Church for this age. The first Christians managed this in a world that was entirely at odds with their faith.

The pro-life campaign is far from over. Abortion would still be illegal in Ireland until legislation is passed to actually legalise it, and there’ll very likely be debates and campaigns during that timeframe. The issue will be framed somewhat differently then.

Ordering Results in DataTables.js by JSON-Defined Columns

Tags

, , , , ,

The main DataTables.js API call is straightforward:


function SetupDataTable(data) {
var c = JSON.parse(data);
var url = ResolveUrl("~/Search/JsonResults");

table = $("#SearchResultsTable").DataTable({
"pagingType": "full_numbers",
"pageLength": 10,
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],
"processing": true,
"serverSide": true,
"ajax": url,
"columns": c,
});

Aside from calling the API to render the DataTable, this JavaScript function makes a request to the /Search/JsonResults controller action when a page load is triggered. The controller action, in turn, will fetch the subsequent x number of records from the source. Set the ‘serverside‘ attribute to ‘true‘ for this.

The (abbreviated) controller action for this originally looked something like:

Ordering results in DataTables should be easy, yes? Actually, no, it wasn’t, since the application here used a single DataTable instance to present tabled data for doctors, organisations, third-party providers, other personnel, sites, tests, etc. In this case, the data fields/columns are defined by the JSON response from the controller, and they’ll change according to the dataset set being selected by the user.

This was my initial code, simply to get a working LINQ query and to create a placeholder for a dynamic variable:


var rows = results.DataSet.AsEnumerable().OrderBy(r =>
r.Field("Organisation Postcode")).Skip(model.start - 1).Take(model.length);

The above is a LINQ statement to sort the data (ascending) by Organisation Postcode – I picked that variable arbitraily from the JSON response. We use DataSet to create an in-memory representation of the data being fetched, so the DataAdapter would limit the read volume to the number of records being requested by DataTables.js. LINQ is used to query this in-memory data instead of the database itself.

What we need to do now is replace the ‘Organisation Postcode‘ with something that could dynamically represent any column name in the JSON response. The LINQ queries I ended up with were:


var sortedResults = order.column == 0 ? results.DataSet.AsEnumerable() :


order.dir == "desc" ? results.DataSet.AsEnumerable().OrderByDescending(o=> o.ItemArray[order.column] is DBNull ? DateTime.MinValue : o.ItemArray[order.column]) :


results.DataSet.AsEnumerable().OrderBy(o => o.ItemArray[order.column] is DBNull ? DateTime.MinValue : o.ItemArray[order.column]);

And the Skip() and Take() operations have been shifted to the row creation loop:

Here we have roughly the same thing as before:
results.DataSet.AsEnumerable().OrderBy()

Passing a somewhat different LINQ statement:

o => o.ItemArray[order.column] is DBNull ? DateTime.MinValue : o.ItemArray[order.column]

In the first part, ‘o => o.ItemArray[order.column]‘, ‘o‘ represents the DataRow in the DataSet. It means pick value ‘order.column‘ from the ItemArray, and order the output by that value.

The local variable is derived from:

var order = new Order() { column = int.Parse(Request["order[0][column]"]), dir = Request["order[0][dir]"] };

This line, in turn, creates a new instance of the following class:

public class Order
{
public int column { get; set; }
public string dir { get; set; }
}

Now, it might be the case that null values are returned for a column, which screws the ability to pick that column as a sorting criteria, so we use the following to populate the null fields with whatever is derived from DateTime.MinValue:
is DBNull ? DateTime.MinValue

The above is a short-hand way of creating an if/then statement. If the value is null, set the value to DateTime.Min.

Note: Parsing JSON Response to Get Columns

There is another method in the SearchController:

Set the variable ‘result‘ simply as the ‘[‘ character to begin with, to mark the beginning of an array.
In the next instruction, if the result is not ‘[‘, in other words, if there’s already something in the array, we append a comma to mark the end of the last element before executing the next instruction. If we’re not at the start of an empty array, ‘result‘ is appended with:
{ "data": "{0}", column.logical_name }

The ‘column.logical_name‘ refers to a string coming from the database table that identifies it as a column name.
After the array has been populated, ‘]‘ is appended to ‘result‘, to mark the end of the array, and it is returned to the calling function as a JSON response.

The Book of Samurai: The Collected Scrolls of the Natori-Ryu

Tags

, , , ,

Antony Cummins seems pretty knowledgeable about the Samurai and warfare in feudal Japan, and, intrigued by his attempt to recreate the Natori-ryu as a modern-day Samurai school and his claims to have translated its syllabus from the 17th century, I bought myself The Book of Samurai.

Generally I like his material very much, but the one serious criticism I really should mention, since there’s a lot of this on YouTube, is his demonstration of rather careless handling of Samurai swords. Yes, I know that one doesn’t need training to cut things with a katana, but those things are bloody dangerous. An untrained person screwing around with one is liable to seriously injure themselves and others around them. Several times Cummins came dangerously close to severing his axillary artery during his ‘speed draws’.
Before doing anything with a 3ft live blade, one should spend a few years (at least) practising with a bokken under the guidance of a Sensei who knows the history and is fussy about traditions, etiquette, techniques, discipline, etc. These are observed for very good reasons. Learn to develop and ‘extend’ Ki so there’s control and precision in the bokken’s movements, develop the constant mindfulness of everything around you.

Anyway… the premise of The Book of Samurai is the Natori-Ryu was founded sometime in the 1500s, to circulate the teachings of the then Samurai with a syllabus that focussed on things related, directly and tangentially, to warfare.
It was after 1654, we’re told, that a Natori Masazumi became the master of the Natori-Ryu. He was to collate the Samurai teachings into a syllabus and create an encyclopaedia of all things Samurai, and this expanded into many other areas than warfare, tactics and strategy. It is within the scrolls that we find information about the Ninja/Shinobi arts, though I think you’d find that in Cummins’ other book, The Book of Ninja.

The Book of Samurai appears to be a pretty decent and credible work. My Aikido instructor, who’s far more knowledgeable about Samurai-related literature, thinks it’s legit. The caveats are that Cummins himself isn’t conversant or literate in Japanese, and the absence of illustrations/photographs of the source material makes it difficult to verify independently.
Personally I believe, at the very least, the book reveals to us subjects that were addressed in the source material, and what was generally written. This is why, even though it’s excellent as a syllabus and educational, I approach it with skepticism.

As a stand-alone book, the content is excellent. Aside from what we’d expect in a Samurai manual, much of the syllabus is remarkably practical today. For example, there’s an etiquette and strategies for preventing conflict, its escalation and other problems that might ensue. There’s advice on travelling at night, and what to do when confronted by a group of potential attackers. You’ll also find sections on emergency preparedness, with advice that’s very similar to what’s given in a corporate fire safety training session. Anyone who’s into the whole Ninjutsu tradecraft thing would certainly like it.

A Solution for Synchronising and Sharing Encrypted Text

Tags

, , ,

The SafeNotes application caught my interest the other day, while casually browsing the Play Store. Initially I thought it was simply the usual password protected notes thing with a nice UI. The application is pretty straightforward to use. Just press on the key icon to set a password for a note, and the padlock icon to encrypt or decrypt it.

Then I noticed the ‘Add existing note‘ option. It turns out the application can be used to sync notes with a site called ‘ProtectedText.com‘, that stores the ciphertext.

ProtectedText.com

Visiting the URL, we get a rather basic-looking site, which I haven’t come across before. It’s a service for storing encrypted notes, which can be used with or without Safe Notes. The encryption is handled by a main.js file which encrypts and decrypts the content locally, so the plaintext should never be stored on the server.
I’ve briefly examined the JavaScript, and it appears pretty legit. A WireShark capture during a browser session with one of my sites here revealed nothing in plaintext beyond a DNS lookup for protectedtext.com.

Each text file is referred to as a ‘site’, and there is a reason for this. Entering a unique name in the text field will create a new ‘site’ at the URI, and each tab could be viewed as an individual page. If several people know the full address and the password, they could use the site as a ‘drop box’ or a private Web site.

To sync the Safe Notes application with a site, just press the ‘Add existing note‘ option, enter the note’s URL, and then enter the password for it.

After the application is synched, it’s simply a matter of uploading or downloading changes. I’m not sure if there’s a version control system for multiple users.