Zum Inhalt

Just notes... Posts

Linkdump KW10/2016

Zeal – Praktisch um Dokumentationen verschiedener Sprachen/Frameworks offline verfügbar zu machen (Cross-Plattform)

Announcing SQL Server on Linux – Hell freezes over! Schon sehr interessant, welchen Wandel Microsoft in den letzten Jahren vollzogen hat. Es wird sich noch zeigen müssen, welche langfristige Strategie dahinter steckt.

What Happens To Older Programmers/Developers? – Im Kern eigentlich immer die gleiche Aussage und meiner Meinung nach auch relativ allgemeingültig für andere Berufe. Wer gedanklich stehen bleibt und sich nicht permanent weiter entwickelt, wird nicht nur körperlich alt.

Do Fewer Things, Better – Entscheidend ist, dass man sich auf wenige Dinge konzentriert und diese dann versucht zur Meisterschaft zu führen.

GitHub lock-in? – Solange man Dinge nicht selber betreibt, hat man immer eine gewisse Art von Vendor Lock-in. Allerdings hat man auch einen Vendor Lock-in, wenn man ein proprietäres Produkt, in diesem Fall passt Team Foundation Server ganz gut, auf eigener Hardware betreibt. Hiermit kann man auch nicht komplett ohne Aufwand auf eine andere Lösung wechseln.

9 Todsichere Wege, Mitarbeiter Zu Demotivieren – Wie wahr, wie wahr. Gerade die Punkte sechs und neun sind in meinen Augen wirkliche Motivationskiller.

TIL – Spaß mit Bitmasken

Häufiger hat man die Anforderung bestimmte Einstellungen zu speichern. In manchen Fällen kann man pro Einstellung bspw. ein Datenbankfeld verwenden und jeweils mit einem Tinyint den Zustand speichern. Allerdings gibt es auch Fälle in denen es Sinn ergeben kann hierfür eine Bitmaske zu verwenden.

Hilfreich ist, dass das .NET Framework alle Werkzeuge, auch für die Konvertierungen zwischen den verschiedenen Datentypen, von Haus aus schon mitbringt.

Hierzu kann man einfach eine simple Enumeration erzeugen und mittels des „Flags“ Attribut kennzeichnen, dass die Enumeration auch als Bitfeld genutzt werden kann.

Ein einfaches Beispiel hierfür kann wie folgt aussehen:

[Flags]
public enum EditDataMode
{
    Create = 1,
    Read = 2,
    Update = 4,
    Delete = 8
}

Eine Instanz kann nun wie folgt erzeugt werden.

EditDataMode dataMode = EditDataMode.Read | EditDataMode.Create | EditDataMode.Delete;

Mittels einer einfachen Hilfsmethode kann man nun prüfen, welches Flag gesetzt ist.

static bool IsFlagSet(EditDataMode bitmask, EditDataMode flag)
{
    return (bitmask & flag) != 0;
}

Nun kann man bspw. prüfen, ob das „Create“-Flag gesetzt ist.

if (IsFlagSet(dataMode, EditDataMode.Create))
{
    Console.WriteLine("Create flag is set.");
}

Praktisch ist, dass man diesen Wert, also die Repräsentierung der Instanz auch als int oder string ausgeben kann.

Console.WriteLine("From EditDataMode to int: {0}", (int)dataMode);
Console.WriteLine("From EditDataMode to string (bin): {0}", Convert.ToString((int)dataMode, 2));

Auch der umgekehrte Weg ist so einfach zu realisieren. Hat man die Bitmask in irgendeiner Form als string gespeichert, so kann man diesen auch einfach wieder in Klassen-Objekt verwandeln.

string input = "0011";
Console.WriteLine("Input: {0}", input);
int convertedInput2Bin = Convert.ToInt32(input, 2);
 
Console.WriteLine("Converted input from string to int: {0}", convertedInput2Bin);
EditDataMode inputDataMode = (EditDataMode) convertedInput2Bin;
Console.WriteLine("EditDataMode to string: {0}", inputDataMode.ToString());

Ein vollständiges Beispiel habe ich bei Github abgelegt.

ExploBitmask

Quellen:

Keine SharePoint Developer Zertifizierungen mehr

Seit fast 3 Jahren bin ich beruflich im SharePoint Umfeld unterwegs, lese viele Blogs, doch die folgende Meldung der letzten Tage ist irgendwie komplett an mir vorbei gegangen.

Gefunden habe ich diese Nachricht gerade in einem Blogbeitrag, auf den ich durch Zufall bei Xing aufmerksam geworden bin.

Wirklich interessant finde ich daran, dass Microsoft hiermit, meiner Meinung nach, noch einmal mehr unterstreicht, dass sie immer mehr den Fokus auf das neue App-Model legen wollen. In seinem Beitrag bringt es Carsten Büttemeier finde ich ganz gut auf den Punkt.
Diese Ausrichtung mag zwar am Reißbrett für einen Produktmanager gut aussehen, geht aber an der Realität vorbei. Farm Solutions werden, meiner Meinung nach, noch lange eine große Rolle spielen, gerade bei Unternehmen, die aus welchen Grund auch immer nicht in die Cloud gehen wollen oder können.

Use browser console to register CustomAction element

Of course it is possible to register a CustomAction using a declarative solution. Nevertheless it is also possible to do this directly from the browser without creating any declarative XML. You do not even need the help of the „Script Editor“ web part which is normally used to do something like this in SharePoint.

You can simply execute the following code from within the JS console of your browser after you have navigated to the site where you would like to register the action.

function AddCustomActions() {
	var clientContext = new SP.ClientContext();
	var site = clientContext.get_web();
	var UserCustomActions = site.get_userCustomActions();
 
	var newUserCustomAction = UserCustomActions.add();
	newUserCustomAction.set_location('ScriptLink');	   
	newUserCustomAction.set_scriptSrc('~SiteCollection/SiteAssets/customscript.js');
	newUserCustomAction.set_sequence(3);
	newUserCustomAction.set_title('custom script');
	newUserCustomAction.set_description('');
	newUserCustomAction.update();
 
	clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}
function onQuerySucceeded(sender, args) {
	alert('New custom action added to Site.\n\nRefresh the page.');
}
function onQueryFailed(sender, args) {
	alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
AddCustomActions();

If you would like to set different options of the UserCustomAction then you simply grab the first 4 lines of the function „AddCustomActions“ and modify it in the JS console of your browser. Moreover the SP.USerCustomAction object is of course documented in MSDN.

Furthermore it also possible to remove UserCustomActions in the same way. To do this you need to get the ID of the UserCustomAction so that you know which one needs to be deleted. For this you can use the following script which lists all registered UserCustomActions.

function ListCustomAction() {
	this.clientContext = new SP.ClientContext();
	var site = clientContext.get_web();
	this.UserCustomActions = site.get_userCustomActions();
	clientContext.load(UserCustomActions);
	clientContext.executeQueryAsync(Function.createDelegate(this, this.listActions), Function.createDelegate(this, this.onQueryFailed));
}
 
function listActions() {
	var customActionEnumerator = UserCustomActions.getEnumerator();
	var actionID;
	while (customActionEnumerator.moveNext()) {
		var oUserCustomAction = customActionEnumerator.get_current();
		console.log(oUserCustomAction.get_title() + ',' + oUserCustomAction.get_id());        
	}
}
 
function onQueryFailed(sender, args) {
	alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
 
ListCustomAction();

Simply copy the ID of the UserCustomAction which should be removed and insert it into the following script.

function RemoveCustomAction() {
	this.clientContext = new SP.ClientContext();
	var site = clientContext.get_web();
	this.UserCustomActions = site.get_userCustomActions();
	clientContext.load(UserCustomActions);
	clientContext.executeQueryAsync(Function.createDelegate(this, this.deleteAction), Function.createDelegate(this, this.onQueryFailed));
}
 
function deleteAction() {
	var customActionEnumerator = UserCustomActions.getEnumerator();
	var actionID;
	while (customActionEnumerator.moveNext()) {
		var oUserCustomAction = customActionEnumerator.get_current();
		console.log(oUserCustomAction.get_title() + ',' + oUserCustomAction.get_id());
		if (oUserCustomAction.get_id().toString() === 'INSERT_CUSTOMACTION_ID_HERE') {
			actionID = oUserCustomAction.get_id();
		}
	}
	var customActionToDelete = UserCustomActions.getById(actionID);
	console.log(customActionToDelete);
	customActionToDelete.deleteObject();
	clientContext.load(customActionToDelete);
	clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}
 
function onQuerySucceeded() {
	alert('Custom action removed');
}
 
function onQueryFailed(sender, args) {
		alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
 
RemoveCustomAction();

IMPORTANT: You can’t use absolute URL for „set_scriptSrc“ like „http://sharepoint/sites/mysitecollection/SiteAssets/customscript.js“ as this would cause some trouble because you would not be able to access your site collection as you will see the yellow ASP error page. If you read this note too late you can simply clear all UserCustomActions which have been registered for a site with the following PowerShell script. The script needs to be run on a server of the farm as it is mostly the case for SharePoint PowerShell scripts.

$site = get-spsite SITE-COLLECTION-URL
$web = $site.OpenWeb()
$web.UserCustomActions.Clear()

If you have any question or comment just drop me a note below.

SPList.WriteSecurity – make a SharePoint list kind of read only

According to the description of MSDN you prevent users from editing items of list using the property „WriteSecurity“. For this you need to change the value to „4“. You can do this via GUI or using the PowerShell.

PowerShell

$site = Get-SPSite http://sharepoint/sites/site1
$web = $site.OpenWeb()
$web.AllowUnsafeUpdate = $true
$list = $web.Lists[„ListToProtect“]
$list.WriteSecurity = 4
$list.Update()

It is important to know that this property only affects users which are members of the site collection administrators.

Resources:
SPList.WriteSecurity property (Microsoft.SharePoint)

Quicklinks KW08/2014

Quicklinks KW07/2014

Quicklinks KW06/2014

Dieses Mal sind es ein paar mehr Quicklinks, da ich einfach vergessen habe diese in den vergangenen Woche zu veröffentlichen.