28
Nummer 128 maart 2016 SDN Magazine verschijnt elk kwartaal en is een uitgave van Software Development Network www.sdn.nl IN DIT NUMMER O.A.: Plug-in ontwikkeling op Dynamics CRM < ASP.NET Core 1.0 Docfx helps us make documentation easier for .NET < Goodbye HTML helpers and hello TagHelpers! < Veilig beheren van Azure Resources vanuit C# < SOFTWARE DEVELOPMENT NETWORK MAGAZINE 128 ISSN: 2211-6486

SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

Nummer 128 maart 2016 SDN Magazine verschijnt elk kwartaal en is een uitgave van Software Development Network

www.sdn.nl

IN DIT NUMMER O.A.:

Plug-in ontwikkeling op Dynamics CRM <ASP.NET Core 1.0

Docfx helps us make documentation easier for .NET < Goodbye HTML helpers and hello TagHelpers! <Veilig beheren van Azure Resources vanuit C# <

SOFTWARE DEVELOPMENT NETWORK

MAGAZINE

128

ISSN: 2211-6486

Page 3: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

magazine voor software development 3

ColofonUitgave:Software Development NetworkVierentwintigste jaargangNo. 128 • maart 2016

Bestuur van SDN:Marcel Meijer, voorzitterRob Suurland, penningmeesterRemi Caron, secretaris

Redactie:Marcel Meijer([email protected])

Aan dit magazine werd meegewerkt door:Roel Hans Bethlehem, Bob Swart, Maartenvan Stam, Arjen Bos, Fanie Reynders, RobSuurland, Remi Caron, Marcel Meijer en natuurlijk alle auteurs!

Listings:Zie de website www.sdn.nl voor eventuelesource files uit deze uitgave.

Contact:Software Development NetworkPostbus 506, 7100 AM WinterswijkTel. (085) 21 01 310E-mail: [email protected]

Vormgeving en opmaak:Reclamebureau Bij Dageraad, Winterswijkwww.bijdageraad.nl

©2015 Alle rechten voorbehouden. Niets uitdeze uitgave mag worden overgenomen opwelke wijze dan ook zonder voorafgaandeschriftelijke toestemming van SDN. Tenzijanders vermeld zijn artikelen op persoonlijketitel geschreven en verwoorden zij dus nietnoodzakelijkerwijs de mening van het be-stuur en/of de redactie. Alle in dit magazinegenoemde handelsmerken zijn het eigen-dom van hun respectievelijke eigenaren.

AdverteerdersMicrosoft 2Achmea 28

Adverteren?Informatie over adverteren en de adverten-tietarieven kunt u vinden op www.sdn.nlonder de rubriek Magazine.

voorwoord

Beste SDN Magazine lezer,

Nog een kleine maand en de Build conferentie zal weer plaats vinden. Ook deze editie was na enkele minuten uitverkocht. Wordt je als event organisator toch best jaloers van. De afgelopen jaren werd er altijd hardware weggegeven aan het publiek,maar dit jaar zouden ze dat niet doen. Mocht je niet in de gelegenheid zijn om naarSan Francisco te gaan, gelukkig wordt de keynote met alle belangrijke mededelingenlive en integraal uitgezonden. De SDN en de gezamenlijke Nederlandse usergroe-pen hebben weer een sponsor gevonden waar we gezamenlijk de keynote kunnenbekijken. Afsluitend kunnen we dan discussiëren over de nieuwtjes en het getoonde.In onze magazines en events komen we zeker terug op de inhoud.

De Techdays zijn daarom verplaatst naar het najaar. Je zult ons daar zeker weer zienen horen. DEVintersection zal ook weer naar Nederland komen en wij willen rondomdeze conferentie ook iets doen. Hou onze nieuwsbrieven in de gaten en reken in elkgeval op een korting.

Dit magazine bevat weer een paar gave artikelen van je collega’s. Hoe zij met denieuwe technieken hebben gespeeld en hoe zij het hebben ingezet. Altijd leuk om deervaringen te lezen voordat je er zelf mee gaat werken. Bas, Cary, Fanie, Kornelis,Henry, Danny, Roel Hans en Wouter hebben hun uiterste best gedaan om hun ervaringen mooi vorm te geven. Over Delphi, CRM, DocFX, DNN 8, Azure Resources, ASP.NET Core Project.json, Ubuntu en VS Team Services.

Weet je dat Iedereen het in zich heeft om een artikel te schrijven? En weet je dat wijaltijd kansen geven om dat ook te doen? Dus heb je zin om zelf een artikel te schrijven of een sessie te doen, meld je bij ons. We helpen je graag verder.

Veel leesplezier, tot het SDN event en Build keynote viewing event.

Groeten,

Marcel Meijer eindredacteur Magazine en Voorzitter SDN •

Page 4: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

Inhoud03 VoorwoordMarcel Meijer

04 Inhoudsopgave

04 Agenda

05 Plug-in ontwikkeling op Dynamics CRMBas van de Sande

08 Bi-Directional Coupling: Here's One Way to Avoid It

Cary Jensen

11 Docfx helps us make documentation easier for .NET

Fanie Reijnders

13 Mijn eerste indruk van de DNN 8 release

Kornelis Pieters

15 Veilig beheren van Azure Resources vanuit C#

Henry Been

18 ASP.NET Core 1.0: Goodbye HTML helpers and hello TagHelpers!

Danny van der Kraan

23 Migrate a .csproj frompackage.config to project.json

Fanie Reijnders

24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V

Roel Hans Bethlehem

26 Code searchin Visual Studio Team Services

Wouter de Kort

• maart Magazine 128

• 30 maart - 1 april Build Conference

• 8 april SDN event

• 16 april Global Azure Bootcamp

• mei Magazine 129

• 10 juni SDN event

• september Magazine 130

• 16 september SDN event

• 26 - 30 september Ignite Conference

• 4-5 oktober TechDays

• november Magazine 131

Agenda 2016

Page 5: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

.NET Bas van de Sande

Wat is een plug-in?Een plug-in is een extra stukje maatwerk functionaliteit dat wordt ge-activeerd op het moment dat wijzigingen binnen Dynamics CRM wor-den opgeslagen. Als ontwikkelaar kan je plug-ins gebruiken omDynamics CRM om te vormen in het systeem waar de gebruikers meekunnen werken.Wat er dan in feite gebeurt, is dat de gemaakte wijziging in een mes-sage wordt verpakt. Deze message wordt door een messaging pipe-line wordt gehaald voordat de entiteit uiteindelijk wordt opgeslagen inde database van CRM. Het bericht moet succesvol door alle fasen binnen de pipeline heen.Op het moment dat in een van de fasen een fout optreedt, dan wordtde executie afgebroken en worden de wijzigingen niet opgeslagen!

Binnen de messaging pipeline zijn een aantal fasen waar het berichtdoorheen gaat, te weten:• Stage 10 - Validation

In deze fase kan je extra validatie loslaten op de data in de entiteit.

Plug-in ontwikkeling opDynamics CRMIn mijn vorige artikelen over Dynamics CRM heb ik jullie in vogelvlucht meegenomen door Microsoft Dynamics CRM. Ik heb ik hoofdlijnen laten zien hoe Dynamics CRM in elkaar zit enheb ik laten zien op welke vlakken je binnen CRM kan customizen en ontwikkelen (zowel clientside als server side). In dit artikel ga ik met een hoeksteen van Dynamics CRM aan de slag; dePlug-in.

• Stage 20 - Pre OperationIn deze fase is de data nog niet opgeslagen in de database. Hierkan de data nog worden verrijkt of worden aangepast. In deze stap begint de transactie.

• Stage 30 - Actual OperationIn deze fase wordt de data opgeslagen in de database van CRM.Dit is een systeem fase, we hebben hierop geen enkele invloed.

• Stage 40 - Post OperationIn deze fase kunnen we nabewerkingen op de opgeslagen datadoen. Met de voltooiing van deze fase wordt de transactie succes-vol afgesloten en is de data definitief opgeslagen in CRM.

Wat heb je nodig om plug-ins te ontwikkelen?Om plug-ins voor Dynamics CRM te kunnen ontwikkelen heb je naastVisual Studio (C# of VB.Net) de Dynamics CRM SDK nodig. Voorzowel CRM online als CRM on-premise gebruik je dezelfde SDK entools. Waar je wel op moet letten is dat je de juiste versie van de SDKgebruikt (2016, 2015, 2013 of ouder). De SDK is te downloaden bij Microsoft.Verder heb je nog een Dynamics CRM omgeving nodig. Deze kanlokaal, op het netwerk of on-line zijn. Voor ontwikkeling is het het han-digst als je een CRM on-premise versie gebruikt. De debugging mo-gelijkheden zijn hier uitgebreider dan op CRM online. Het is zeer zeker de moeite waard om de SDK nadat je deze hebt uit-gepakt te bekijken. Je vindt hier onder andere:

magazine voor software development 5

Page 6: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

MAGAZINE

6

Als dat is gedaan, dan kunnen we een stap verder gaan. We halen nude entiteit uit de input parameters. Deze is voor create, update en delete berichten altijd te vinden onder ”Target”. Vervolgens kunnen we via de PluginExecutionContext bepalen metwat voor type bericht we hebben te maken en in welke fase dit berichtzich bevindt. In onderstaand voorbeeld luisteren we alleen naar eenCreate bericht in stage 20 (pre operation). Tenslotte overschrijven we de waarde van een van de velden in de en-titeit. We hoeven de wijziging niet op te slaan. Deze wordt automa-tisch meegenomen in de execution pipeline.

Op dit moment hebben we in principe onze eerste plugin geschreven.Wat nu nog rest is het signen (CRM accepteert alleen maar signed assemblies), compileren en installeren en registreren met de Plugin Registration Tool uit de SDK.

Registreren plug-in en test runNa het opstarten van de Plugin Registration Tool kunnen we de plug-in assembly toevoegen aan CRM. We kiezen hiervoor Register, Register New Assembly uit het menu. Een pop-up komt naar voren waarin we de plug-in dll kunnen selec-teren.

• CrmSDK20xx.chmUitgebreide SDK documentatie.

• BinHierin zijn de Dynamics CRM dll’s te vinden die je nodig hebt. Jekan deze ook via Nuget binnenhalen.

• ToolsNuttige tools, waaronder de plug-in registration tool. De tool die jenodig hebt om je plug-in dll te registeren in CRM met de bijbeho-rende plugin stappen en images.

My first plug-inWe zijn nu klaar om onze eerste plug-in te ontwikkelen. We openenhiervoor Visual Studio en kiezen hier voor een class library project.

Om tegen Dynamics CRM te kunnen programmeren moeten we eenaantal references leggen, te weten Microsoft.Xrm.Sdk.dll en Micro-soft.CRM.Sdk.Proxy.dll.

De plugin ziet er in basis een public class die de IPlugin interface im-plementeert. De IPlugin interface bevat alleen een Execute method,welke we moeten implementeren om iets met de plug-in te kunnendoen.

Als eerste stap moet binnen de plug-in een PluginExecutionContext eneen OrganizationService worden gemaakt. Uit de PluginExecutionContext haal je alle gegevens omtrent het be-richt dat door de message pipeline heen gaat. Denk hierbij aan Input-Parameters, EntityImages, stage en MessageName.De OrganizationService heb je nodig om met Dynamics CRM te kun-nen communiceren.

.NET

Page 7: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

We laten de defaults staan en klikken op de Register Selected Pluginsbutton. De plug-in wordt nu geuploaded naar Dyanmics CRM. Wekunnen vervolgens gaan bepalen op welke stap de plug-in moet wor-den uitgevoerd.

Na het openen van de MyFirstPlugin assembly, zien we de plugin diewe hebben gemaakt. We selecteren deze en klikken op de rechtermuisknop. In het context menu kiezen we voor “Register New Step”.Het volgende scherm verschijnt.

We vullen hier de message naam in, in ons geval is dit “Create”. Ver-volgens geven we op, op welke entiteit de plug-in wordt geregistreerd.Tenslotte geven we de stage of execution op, in ons geval pre-opera-tion. Na het registeren van de stap ziet het scherm er als volgt uit:

We kunnen nu het accountscherm in CRM openen, en hier een nieuwaccount gaan opvoeren.Wanneer we het nieuwe account saven, zal de naam door de plug-inwordt gewijzigd in “My first plugin”.

Mission accomplished!

ResumerendIn dit artikel heb ik in vogelvlucht laten zien wat er komt kijken bij hetontwikkelen van een plug-in voor Dynamics CRM. In dit artikel ben iknog niet ingegaan op de OrganizationService en het gebruik van EntityImages. In een volgend artikel zal ik daar verder op ingaan. •

Bas van de Sande

Bas van de Sande heeft zich sinds1995 gespecialiseerd in software-ontwikkeling en advisering op hetMicrosoft platform. Hij heeft zichsinds 2005 voornamelijk bezig ge-houden met SharePoint en Micro-soft.Net. Op dit moment ligt zijnfocus op Microsoft CRM en blogt hijzeer actief over zijn ervaringen met

CRM. Bas is werkzaam als Senior Software Developer/Architectbij CRM Partners.

magazine voor software development 7

.NET

Page 8: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

DELPHI Cary Jensen

This situation is known as uni-directional coupling, and it occurs in almost every Delphi application. For example, in order for a VCL formto include a button, the form must use the Vcl.StdCtrls unit, otherwiseit would not be possible for the form to call the constructor of the TButton class in order to instantiate a button. Uni-directional couplingis not bad - it is a necessity.

There is another form of coupling called bi-directional coupling, and itis not always so benign. Bi-directional coupling occurs when two unitsuse each other.

Understanding the IssueWhile bi-directional coupling is not always a problem, there are a number of circumstances where it should be avoided at all costs. Specifically, code (classes, pure functions, interfaces, and the like) thatcan be used in a variety of applications should not be coupled, bi-directionally, to code that is specific to one application.

Imagine that you have a form that you use to print reports for a parti-cular application. During the course of your development, you build autility unit that performs a number of different calculations and trans-formations on data in a generalized way. During your development youwrite a couple of routines in this utility unit that perform specific mani-pulations on one or more reports in the reporting unit. You have justnow coupled, bi-directionally, the reports unit to the utility unit. Specifically, the reports unit must use the utility unit, in order to access the symbols declared in the utility unit's interface section, andthe utility unit must use the reports unit in order to manipulate someof the reports.

If you only use this utility unit in this one application this bi-directionalcoupling will go unnoticed. However, as soon as you use the utilityunit in another application you will discover the downside of bi-direc-tional coupling, which is that you must also use the reports unit in thisnew application, whether or not you need any of the reports that it defines. In more general terms, when two units are coupled bi-directionally, you cannot use one of those units in another applicationwithout also using the other.

Depending on the units involved in this bi-directional coupling, the problems that it introduces can be extreme. For example, if you wereto couple a utility unit to the main form of an application, you will notbe able to use that utility unit in any other applications without

It is not unusual for code in one unit to need to interact with code in another unit. For example,you may have a form that is defined in one unit and it needs to use a class defined in anotherunit. So long as the class is defined in the interface section of the second unit, the form in thefirst unit can "see" that class simply by using the second unit, specifically by including the second unit in either its interface or implementation section uses clause.

Bi-Directional Coupling:Here's One Way to Avoid It

including every single form from the original application in the new application. Over the years I have seen many cases where the casualbi-directional coupling of an otherwise generic unit meant that the generic unit could not be added to another application without including dozens of unnecessary units from some original application,and the process of removing this coupling can take days or weeks,and requires extensive re-testing and debugging.

Note: When using Delphi's smart linker, the symbols that are not explicitly used are generally not compiled into the resulting applica-tion. However, their resources are! In other words, when a form appears in a uses clause somewhere in your application, the form's resource (the .dfm file, specifically), is unconditionally linked into yourexecutable.

Avoiding Bi-Directional Coupling Using Method PointersThe truth is that code in two or more units must be able to interact.Fortunately, there are a number of techniques that you can employthat permits this interaction without producing bi-directional coupling.In this article I am going to demonstrate one of these - method pointers.

A method pointer is a type that can hold a reference to a method ofan object. Method pointers are the foundation upon which event handlers are built. Think about if for a minute. The TButton class ex-poses a property called OnClick of type TNotifyEvent. So long as yourform's unit includes the Vcl.StdCtrls unit in its uses clause (or FMX.StdCtrls), the form can assigned an event handler to this property, and the button can call this event even though the form'sunit is not in a uses clause of the Vcl.StdCtrls unit (or FMX.StdCtrlsunit). Yes, the form's unit is dependent on the unit in which the buttonis declared, but the reverse is not true. As a result, uni-directional coupling is present, not bi-directional, and you can use the button inalmost any application without the button using any of the units withwhich it must interact.

This might seem like a minor point, but when you are designing classes that need to interact with each other, you should give some serious thought as to how they interact.

An ExampleI addressed this situation recently. I was designing a class that I intended to reuse across a number of applications. This class, which

MAGAZINE

8

Page 9: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

DELPHI

{ Public declarations }

property OnUpdate: TNotifyEvent read FOnUpdate write FO-

nUpdate;

property OnUpdateGrid: TGridUpdateEvent read FOnUpdate-

Grid

write FOnUpdateGrid;

constructor Create(AOwner: TComponent; Year: Integer);

overload;

end;

To begin with, let's ignore the declaration of TGridUpdateEvent, andinstead focus on the OnUpdate property of the TFrame descendant.This property is of type TNotifyEvent, a method pointer type declaredin the System.Classes unit. Here is the declaration of TNotifyEvent:

TNotifyEvent = procedure(Sender: TObject) of object;

In short, this declaration says that a value of TNotifyEvent type is aprocedure that takes a single parameter named Sender of type TObject, and that this procedure is a method of an object.

So long as the main form of this application assigns a properly decla-red method to this property, the frame class can invoke that method.Here is the code that performs this task, and it is used as an eventhandler for the AfterPost, AfterDelete, and AfterInsert properties of theframe's ClientDataSet.

procedure TGridFrame.ClientDataSetChanged(DataSet: TData-

Set);

begin

if Assigned(FOnUpdate) then FOnUpdate(Self);

end;

Here is the code that executes on the main form to create the variousframes that it needs.

procedure TForm1.FormCreate(Sender: TObject);

var

GridFrame: TGridFrame;

Year: Integer;

CurrentYear, LastYear: Integer;

begin

CurrentYear :=

ClientDataSet1.FieldByName('SaleYear').AsInteger;

ClientDataSet1.Last;

LastYear := ClientDataSet1.FieldByName('SaleYear').AsInte-

ger;

ClientDataSet1.First;

while CurrentYear <= LastYear do

begin

GridFrame := TGridFrame.Create(Self, CurrentYear);

GridFrame.Name := 'GridFrame' + IntToStr(CurrentYear);

GridFrame.Parent := FlowPanel1;

GridFrame.ClientDataSet1.CloneCursor(Self.ClientData-

Set1, True);

GridFrame.ClientDataSet1.IndexFieldNames := 'SaleYear';

GridFrame.ClientDataSet1.SetRange([CurrentYear], [Cur-

rentYear]);

//Hook up the method pointer

GridFrame.OnUpdate := DoUpdate;

GridFrame.OnUpdateGrid := GridUpdated;

inc(CurrentYear);

end;

end;

was a type of frame, was created at runtime by a class that owned it.Importantly, this frame class needed to inform its owning class thatsomething about it had changed. One way to do this was to exposea public method on the owning class, and call this method from theframe. The problem with this approach is that the frame would needto have knowledge about the owner, which means that the framewould have to have the owner's class within its scope. This wouldproduce bi-directional coupling, since the owner also has to haveknowledge of the frame.

The solution was to expose a method pointer type property on theframe. The owner, after creating an instance of the frame, assigns amethod of the appropriate method pointer type to this frame's property. When it comes time for the frame to inform the owner aboutthe state change, the frame merely needs to verify that something hasassigned a method pointer to this property, after which the frame callsthe method to which this property points.

I have re-created this scenario in the DynamicFrames project. In thisproject I have a main form that creates a different instance of a framefor each different year value in a result set. The running main form, populated with frames that were created dynamically at runtime, isshown in Figure 1.

Fig.1: The main form of the DynamicFrames project

Imagine now that each time there is a change to data displayed in oneof the frames I want to perform some task in the main form. Ratherthan making the two units, the one that declares the form and theother that declares the frame, refer to each other, I exposed a publicmethod on the frame that can be assigned a value by the form. Hereis the declaration of the frame class:

type

TGridUpdateEvent = procedure (Sender: TObject; Company:

string;

SalesPerson: string) of ob-

ject;

TGridFrame = class(TFrame)

DBGrid1: TDBGrid;

DataSource1: TDataSource;

Label1: TLabel;

YearLbl: TLabel;

ClientDataSet1: TClientDataSet;

procedure ClientDataSetChanged(DataSet: TDataSet);

private

{ Private declarations }

FOnUpdate: TNotifyEvent;

FOnUpdateGrid: TGridUpdateEvent;

FYear: Integer;

public

magazine voor software development 9

Page 10: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

DELPHI

It's the fifth line from the bottom that hooks up the frame to the form.Now, the frame can inform the form to do something, even thoughthe frame has absolutely no knowledge about the form.

Here is the implementation of the form's DoUpdate method:

procedure TForm1.DoUpdate(Sender: TObject);

begin

MessageLbl.Caption := 'The frame for ' + TGridFrame(Sen-

der).YearLbl.Caption +

' has been updated';

end;

As you can see, the form, which does have knowledge of the frame,can use the frame's public and published (if available) members to dosomething about the changes that have occurred. In this case, a message is displayed informing the user about in which frame achange has occurred.

procedure TGridFrame.ClientDataSetChanged(DataSet: TDataSet);

begin

if Assigned(FOnUpdateGrid) then

FOnUpdateGrid(Self, ClientDataSet1.FieldByName('Com-

pany').AsString,

ClientDataSet1.FieldByName('SalesPerson').AsString);

end;

A More Complicated ExampleThe limit to this technique as demonstrated with the OnUpdate property of the frame is that the form can only access features visiblefrom the frame's public or published interface. What if the form needsinformation that is not visible, such as private or protected data in theframe?

The answer is that you can create a custom method pointer, and parameters of that method pointer can return those otherwise not-within-scope values in its invocation of the supplied method pointer.

An example of this is found in the frame's unit. Referring back to thatunit's interface type declaration, here is the custom method pointertype.

TGridUpdateEvent = procedure (Sender: TObject; Company:

string;

SalesPerson: string) of object;

In this case, the name of the company and the sales person makingthe sale are parameters. Since the ClientDataSet is visible to the form,it would have been possible to read these values from the ClientDataSet's Fields property, but in reality, the custom method pointercould pass any data, including that stored in strictly private fields, tothe method assigned to this method pointer property.

The property that exposes the frame's TGridUpdateEvent is namedOnUpdateGrid. Here is the line of code in the form's code that, aftercreating each instance of the frame, assigns a method pointer to theframe's OnUpdateGrid property.

GridFrame.OnUpdateGrid := GridUpdated;

And now, here is the implementation of OnUpdateGrid:

procedure TForm1.GridUpdated(Sender: TObject; Company, Sa-

lesPerson: string);

begin

MessageLbl.Caption := 'The frame for ' + TGridFrame(Sen-

der).YearLbl.Caption +

' has been updated for ' + Company +

' and sales person ' + SalesPerson;

end;

Figure 2 shows how this project looks when a value in one of theframes has been modified, and the OnUpdateGrid property of theframe has been hooked up.

Fig. 2: The message on the main form is produced by an invocationfrom the frame

SummaryAny application that needs to use the form in the DynamicFrames project will also need to use the unit in which the frame is defined.That's fine, since this form needs the frame in order to perform its task.By comparison, you can add the frame's unit to any application, andif that application does not require the form as well, it does not needthe form's unit.

You can download this example using the following URL:http://www.JensenDataSystems.com/DynamicFrames.zip •

Cary Jensen

Cary Jensen is Chief Technology Of-ficer of Jensen Data Systems. Since1988 he has built and deployed da-tabase applications in a wide rangeof industries. Cary is an Embarca-dero MVP, a best selling author ofmore than two dozen books on

software development, and holds a Ph.D. in Engineering Psycho-logy, specializing in human-computer interaction. His latest bookis Delphi in Depth: ClientDataSets 2nd Edition. You can learn moreabout this book at http://www.JensenDataSystems/cdsbook2.

MAGAZINE

10

Page 11: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

.NET Fanie Reijnders

Currently supporting languages C# and VB.NET, Docfx is an API documentation generator for .NET. If you have worked with JSDoc orSphinx before, you will notice that Docfx is a similar concept. It doesn’tjust have the ability to directly read the triple-slash comments in code,but also includes a syntax for deep linking to objects and additionalfiles with extra information. These files are written in a special Mark-down format called Docfx Flavored Markdown (DFM) which is completely compatible with GitHub’s Markdown. The documentation generation is based on a pre-defined templatesupporting the Mustache syntax and is completely customizable.

Using DocfxAt the time of writing this article, one can either use the executable directly, from within Visual Studio 2015 or as a command on DNX (.NetExecution Environment).Direct use The quickest way to get started is to get your hands dirty and playaround with this awesome tool. After downloading the latest releaseon GitHub (https://github.com/dotnet/docfx/releases), navigate to yourtarget documentation folder using Command Prompt and initialize adefault project:

This will initiate a configuration file called docfx.json inside the targetdirectory.

Note that I have included a sample C# project under the /src directorythat contains a bunch of sample code and xml comments.

The next step is to actually generate and serve up the documentationusing the given configuration:

This will generate and serve up a compiled copy of the documentationas a static HTML site on http://localhost:8080.

Docfx helps us make documentation easier for .NETOne of the most tedious jobs of being a developer is maintaining documentation, but it shouldn’tbe a difficult task. When writing documentation, one doesn’t always want to be concernedabout how things look per se, but rather how things are communicated. Having to focus on justwriting and not the other stuff is very important.

magazine voor software development 11

Page 12: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

.NET

You can now also combine it with additional content. Here’s an example of a Hello.md file I’ve added to the root directory:

To have this page show up in the navigation and be part of the rest ofthe documentation, we need to also add a toc.yml file containing all thelinks:

After running the build & serve command we now get this result

Using Docfx from within Visual StudioYou can include a documentation build task to run every time you builda project in Visual Studio. Simply add the Docfx.build Nuget package:

This will add the necessary toc.yml and docfx.json files to the projectfor your configuration and the documentation site will be generatedinside the _site folder every time you build the project.

Using Docfx under the .NET Execution Environment (DNX)To run Docfx as a command for DNX, as a prerequisite; the latest version of the .NET Version Manager (DNVM) and the .NET Utilities(DNU) must be installed. Reference the documentation of ASP.NETCore at http://docs.asp.net for more information.After installing all the prerequisites, we need to make sure to targetthe right source for installing Docfx as it depends on the latest releaseversion of ASP.NET Core 1.0.0-rc1, by setting the DNX_FEED environment variable. Thereafter we install the Docfx command forASP.NET Core.

Now that Docfx is a command, we could simply use it to build the documentation site by either executing docfx build (or just docfx) andthen serving it up on a local server:

In closingNow that we’ve seen how easy it is to create, generate and maintaindocumentation for the .NET platform using Docfx, I urge you to go tohttps://dotnet.github.io/docfx to learn more and start playing aroundwith this great tool. Who knows, it might find itself in your next project!•

Fanie Reynders

Fanie Reynders is a technical con-sultant, technology evangelist and aMicrosoft MVP for Visual Studio andDevelopment Technologies that isobsessed with code, architectureand cool new tech in the cloud. Fol-low him on https://twitter.com/Fa-nieReynders and http://reynders.co

MAGAZINE

12

Page 13: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

DOTNETNUKE

Kornelis Pieters

DNN 8 is beschikbaar!Donderdag 14 januari 2016, met belangstelling, heb ik het webinarvan DNNCorp gevolgd over de vernieuwingen van DNN 8: MVC, SPA,JWT. Nuttig en bruikbaar. Maar wanneer is de "echte" versie er nu?Wat schetst mijn verbazing: als ik vrijdagochtend de 15e op kantoorkom, zit er een bericht in mijn mailbox met de aankondiging dat DNN8 vanaf nu beschikbaar is. Mooi! Direct ga ik kijken wat deze finaleversie nu voor ons werken met DNN 8 betekent en daarbij kom ik on-derwerpen tegen die ik graag met u deel. Ik heb uit de release notes(die u ook in de Engelse taal terug kunt vinden op de releasepagina vanDNN Platform op CodePlex) mijn selectie van wetenswaardighedengemaakt.

Breaking changesAls u in de afgelopen periode onze blogs over DNN heeft gevolgd,dan herkent u een aantal van de volgende items:• .NET Framework versie 4.5.1 of hoger is vereist

Een no-brainer, maar wel even aan denken als u een nieuwe instal-latie of upgrade uitvoert

• Verouderde Admin modules zijn weg uit de installatie (SiteLog,Newsletters, Vendors & Banners)Heeft u ze toch nodig (ik kan mij dat haast niet voorstellen) en wiltu over naar DNN 8 (dat kan ik mij dan weer wél voorstellen), dan zijnze te vinden in de DNNCommunity-sectie op GitHub.

• Verouderde navigatieproviders zijn weg uit de installatie (ASP2Menu,DNNDropDown, DNNMenu, DNNTree, Solpart)Opgeruimd staat netjes denk ik dan maar.

• Verouderde functionaliteiten zijn verwijderd (What’s New, FeedBrowser, Widget Framework, Getting Started, Content List)Yes!

• Oude connection-string (appSetting) weg uit de configTja, die gebruikten wij al niet meer sinds DNN 5 ☺.

• Referentie naar de Telerik-controls in een aparte assemblyDat is lastiger, als je DNN 8 gaat gebruiken met bestaande modu-les die Telerik-controls of op Telerik gebaseerde DNN-controls be-nutten, dan moet je een hercompilatie/-build doen met verwijzingnaar de nieuwe assembly. Bij ons "breaken" daardoor een aantalbestaande modules. Niet lastig, maar het moet wel even gebeuren.

• Met diezelfde 'handicap' (breaking) zijn er ook standaardmodules,voorheen bekend als core-modules, die daar last van hebben: FAQ,Feedback, Iframe, Events en Form and List

Als u die gebruikt en dat ook op DNN 8 wilt doen, ga naar de Git-Hub-repositories en kijk naar een update die DNN 8-compliant is.En ongetwijfeld geldt dit ook voor modules van leveranciers.

• Ondersteuning voor IE 8 is wegDaarin is DNN niet alleen: wat ons (en Microsoft) betreft hadden aandat lijstje van niet meer ondersteund ook IE 9 en 10 mogen wordentoegevoegd. Natuurlijk begrijp ik ook, dat de praktijk bij klanten (omdiverse redenen) niet altijd helemaal bij is.

Nieuw voor developersHier beginnen de leuke dingen, van deze vernieuwingen word ik warm:• Support voor SPA- (Single Page Application) en MVC-modules met

nieuwe VS2015-templates voor deze moduletypesBeide soorten gebruiken we al, goed dat we dit nu op een formelerelease kunnen voortzetten.

• Nieuwe API voor settingsBetrouwbaardere oplossing die minder werk vergt, wie wil dat nuniet? Noot: deze opzet is grotendeels door mijn collega Serge ge-maakt en die code hebben we aan DNN gedoneerd.

• Admin- en Hostpagina's maken vanuit de install van een moduleHandig als u het platform met eigen beheerfunctionaliteit uitbreidt.

• Een control om CSS- en/of JS-files te onderdrukken of minificerenHandig, want stapeling van deze files kan nog wel eens een on-voorspelbaar gedrag geven, zeker als je componenten van anderenin je oplossing gebruikt.

• Default.css kan versies hebbenOok een nuttige verbetering: default.css is niet altijd wenselijk enwij ruimen die nogal eens op, nu kunnen we dat beter beheren. Ookverwacht ik dat hierdoor een upgrade van DNN minder verminkingaan de site-skin teweegbrengt door een gewijzigde default.css in dienieuwe versie.

• DNN 8 gebruikt nu WebAPI 2.0Mooi, want dat willen wij ook graag in onze oplossingen doen.

• JSON Web Token (JWT) authenticatie-supportHier moet ik nog even aan wennen; wij waren net lekker op wegmet oAuth 2.0, maar ik begrijp dat JWT flexibeler is en ook geschiktvoor gebruik buiten het framework, bijvoorbeeld voor flexibele enbetrouwbare authenticatie van apps. Nu is deze feature nog BETAin deze release, dus ik kan er inderdaad nog even aan wennen.

De eerste indruk van versie 8 van DNNPlatform. Wat is er en wat kan er? Grote wijzigingen enbreaking changes.

Mijn eerste indruk van de DNN 8 release

In DNN 8 zitten grote wijzigingen enbreaking changes

Een mooie set uitbreidingen waar ik als developer lekker mee uit de voeten kan

magazine voor software development 13

Page 14: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

DOTNETNUKE

Maar er is nog meer!Er is in DNN 8 platform nog veel meer gewijzigd dan hierboven beschreven. Een korte opsomming:• Nieuwe image-handler• Nieuwe default teksteditor (CKEditor) in plaats van de vermaledijde

RadEditor• Alle Admin functionaliteit als losse modules (dus die kun je nu uit

een eigen webapplicatie weglaten, goed voor performance)• DNN is nu een Web Applicatie Project (WAP) in plaats van een Web-

siteproject (WSP). Beter, betrouwbaarder, sneller dus...• Page output-caching zit nu ook in het Open Source DNN-platform

en niet alleen in de betaalde versie• SMTP ondersteunt nu ook TLS-authenticatie. Essentieel als u met

Gmail/Google Apps werkt

Er is nog meer, veel meerDit lijkt wel zo'n irritante Amerikaans getinte televisiereclame: "Wacht,er is nog meer, veel meer"Het is niet mijn bedoeling op deze wijze reclame voor DNN te maken,ik ben gewoon enthousiast over deze nieuwe release, voor zover udat nog niet had opgemaakt uit mijn blog!

Met de zaken die ik hiervoor genoemd heb zijn we er vast nog niet. Indat opzicht doen wij in de komende weken nog een extra ontdek-kingsreis naar de nieuwe mogelijkheden en features. En een deel vandie "features" is ongetwijfeld "unwanted", oftewel: (lastige) bugs. Fouten die nog opgelost moeten worden, zoals wij dat ook in onzeprogrammatuur tegenkomen (ja hoor, niets menselijks is ons vreemd).Ik heb alle vertrouwen dat die bugs opgelost gaan worden en dat wedaarmee met DNN 8 een grote stap vooruit gaan. U ook? •

PlatformsIeder platform heeft inmiddels een laptop, een tablet, een telefoon en een horloge. De verschillen zitten in het aantal leveranciers perplatform en in de operating systems.

Bij Google het OS van de verschillende devices is duidelijkanders. Bij Apple is het OS van de ipad en de iphone gelijk,maar verschillende van de laptop. Bij Microsoft heeft iederedevice inmiddels hetzelfde OS en programmeermodel.

Google

Microsoft

Apple

Allemaal verschillen die aandacht vragen voordat u naar DNN 8 overstapt, maar niet onoverkomelijk

Kornelis Pieters

Gepassioneerde ontwikkelaar dienieuwe technieken en/of uitstapjesin het vak niet schuwt. Rauw, somsdirect, maar valt in het gebruik bestmee.

MAGAZINE

14

OPROEP!Lijkt het je leuk een bijdrage te leveren aan (het volgende) SDNmagazine? We nodigen je van harte uit om een artikel te schrij-ven over je vakgebied,over ontwikkelingen en/ of achtergron-den. Stuur je kopij naar [email protected], er zit een auteur in onsallemaal!

Page 15: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

CLOUD Henry Been

Het komt minder vaak voor dat je vanuit C# je Azure resources wiltbeheren. Toch zijn er scenario’s waarin dat noodzakelijk is. Bijvoor-beeld in zogenaamde multitentant architecturen, waar de data vanelke gebruiker gescheiden is van die van andere gebruikers. In datgeval wil je bijvoorbeeld vanuit je programmacode automatische eenAzureSql Database aanmaken als een nieuwe gebruiker zich registreert. In dit artikel laat ik zien hoe je vanuit een C# applicatie jeAzure resources kunt beheren, met een AzureSql database als voorbeeld. De nadruk leg ik hierbij op het gebruik van een certificaatvoor authenticatie naar Azure. Hiermee kun je beheerstaken uitvoeren zonder gebruikersnamen of wachtwoorden op te hoevennemen in broncode en daarmee source control. Tevens demonstreerik het gebruik van het nieuwe Azure security model: Azure ResourceManager.

Azure Service Management vs. Azure Resource ManagementAls we even meer afstand nemen en bekijken hoe we zaken in Azurekunnen beheren, dan is er veel veranderd het afgelopen jaar. Microsoftheeft hard gewerkt aan het ontwikkelen van een nieuwe portal (Ibiza)naast het bestaande management portal. Er is echter veel meer veranderd dan alleen de gebruikerservaring. De nieuwe portal is gebaseerd op Azure Resource Management (ARM), een nieuwe managementlaag voor de Azure Fabric. ARM is de vervanger vanAzure Service Management (ASM). De managementlaag bepaalt demanier waarop je abstracte onderdelen in Azure, je resources, benadert. Een Azure resource is bijvoorbeeld een AzureSql server, eenCloud Service of een Website.

Het grote probleem van ASM was dat het niet mogelijk was om in detail te bepalen welke gebruiker toegang heeft tot welke resources.Elke beheerder die toegevoegd wordt aan een subscription is een co-administrator en kan dus bij alle resources in je subscription.

Hetzelfde alles-of-niets scenario geldt voor applicaties die je toegangverleent tot je subscription via een management certificate. Je moeteen gebruiker of applicatie dus volledige toegang geven, ook wanneerdit helemaal niet nodig is. De enige manier om autorisaties te beperken bestond uit het aanmaken van meerdere subscriptions.

Met ARM adresseert Microsoft deze tekortkoming in de vorm van RoleBased Access Management (RBAC). Samen met ARM komt ook eenvolledig nieuwe management REST API voor Azure beschikbaar. DezeAPI biedt de mogelijkheid om niet alleen je resources te beheren engroeperen, maar ook wíe welke resources of resourcegroepen magaanmaken, beheren en verwijderen. De mogelijkheden van deze APIkomen dan ook terug in de Ibiza portal.In dit artikel wordt gebruik gemaakt van ARM, via Powershell. Ditomdat nog niet alle benodigde functionaliteit beschikbaar is in de Ibizaportal. De gebruikte Powershell versie is ≥ 1.0.0 (https://www.powershellgallery.com/packages/Azure/1.0.0) en de meest recenteMSOnline module (https://msdn.microsoft.com/en-us/library/jj151815.aspx).

Tabel: Verschillen tussen ASM en ARM

Een applicatie autoriserenTerug naar het doel: Een C# applicatie schrijven die een AzureSql database aan kan maken. Voordat de applicatie geschreven kan worden, moet hij geregistreerd worden in Azure. Gebruikers en applicaties die toegang hebben tot je subscription onder ARM, worden beheerd in een Azure Active Directory. Elke Azure subscriptionis geassocieerd met precies één Azure Active Directory waarin de gebruikers zitten welke toegang hebben tot de subscription. Omdat wachtwoorden opslaan in source control vermeden moet worden, kan gebruik worden gemaakt van een certificaat waarmee deapplicatie zich kan authentiseren tegen bij Azure Active Directory en opbasis van ingestelde privileges toegang krijgt tot de juiste Azure resources. Als uitgangssituatie moet er een Azure Active Directory bestaan met minimaal een gebruiker die ‘Global Admin’ is.

Wanneer je aan de slag gaat met een Azure subscription, is een van de eerste dingen waar jemee te maken krijgt de Azure Portal. In deze portal kun je alles wat je nodig hebt in Azure aan-maken, beheren en ook weer verwijderen. Voorbeelden van dit soort resources zijn een AzureWebsite of een AzureSql database server. Naast de portal kun je gebruik maken van Power shell,een REST API of een cross-platform commandline om je Azure subscription te beheren.

Veilig beheren van AzureResources vanuit C#

Azure Service Management Azure Resource Management

Portal https://manage.windowsazure.com https://portal.azure.com

REST API https://management.core.windows.net https://management.azure.com

Powershell Verb-Azurexxxx Switch-AzureMode (Azure PS < 1.0),Verb-AzureRmxxxx (Azure PS >/ 1.0)

magazine voor software development 15

Page 16: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

CLOUD

Eerst wordt een verbinding naar de Azure Active Directory gelegd.Inloggen met de global administrator gebruiker.

> Connect-MsolService

Nu kan de applicatie in Azure AD geregistreerd worden, hiervoor wordteen Service Principal gebruikt:

> New-MsolServicePrincipal -DisplayName DemoApplication

Het bovenstaande commando geeft na aanmaken van onze applica-tie onder andere het AppPrincipalId terug. Dit is later nog nodig, dussla het op voor later gebruik

> $appPrincipalId = “…”

Nu de applicatie is aangemaakt, kan het certificaat aan de applicatiegekoppeld worden:

> $certificate = New-Object System.Security.Cryptogra-phy.X509Certificates.X509Certificate > $certificate.Import("c:\...\YourApplication.cer")> $binaryCertificate = $certificate.GetRawCertData() > $base64Certificate =[System.Convert]::ToBase64String($binaryCertificate);> New-MsolServicePrincipalCredential -AppPrincipalId$appPrincipalId -Type asymmetric -Value $base64Certi-ficate -Usage verif

Standaard wordt bij het aanmaken van de service principal ook eengebruikersnaam en wachtwoord aangemaakt. Dit wordt verder nietgebruikt, dus kan beter verwijderd worden.Vraag de details van de ap-plicatie en zijn credentials op en noteer het KeyId van de symetric key

> Get-MsolServicePrincipalCredential -AppPrincipalId$appPrincipalId

Verwijder vervolgens het eerder aangemaakte symetrische credentialwat we niet gaan gebruiken

> Remove-MsolServicePrincipalCredential -AppPrincipa-lId $appPrincipalId -KeyIds ($keyId)

De applicatie kan nu authenticeren, maar moet nog rechten krijgenbinnen de subscription. Eerst moet er ingelogd worden op Azure

> Login-AzureRmAccount

Nu kan er een nieuwe resource group ‘Demo’ aangemaakt worden:

> New-AzureRmResourceGroup -Name Demo -Location West-

Europe

Contributor is een standaard rol welke alle rechten bevat behalve hetrecht om anderen rechten toe te kennen. Deze wordt toegekend aande applicatie voor de nieuwe resourcegroup. In de variable $scopewordt de ResourceId ingevuld die het vorige commando terug gaf.

> $scope = "/subscriptions/4...f/resourceGroups/Demo" > New-AzureRoleAssignment -ServicePrincipalName $app-PrincipalId -RoleDefinitionName Contributor -Scope$scope

Het gebruik van de ARM API vanuit onze applicatieNu de applicatie gedefinieerd is en toegang heeft tot de resourcegroup ‘Demo,’ kan er overgestapt worden op C# om vanuit een applicatie een Azure SQL Database aan te maken in deze resourcegroup. Hiervoor moet de applicatie zich authenticeren tegen Azure Active Directory met zijn certifcaat, waarna hij een access token terugkrijgt. Met dit access token kunnen we vervolgens een aanroepnaar Azure doen. In het voorbeeld hieronder wordt gebruik gemaaktvan de NuGet packages Microsoft.Azure.Management.Sql en Microsoft.IdentityModel.Clients.ActiveDirectory.In de listing hieronder is de C# code te zien die gebruikt kan wordenom een nieuwe AzureSqlServer te maken.

In het eerste deel worden vijf variabelen ingevuld. De eerste waardearmLocation bevat de context waarvoor een AD token wordt opge-haald. Deze is voor alle management operaties gelijk. Het subscripti-onId en tenantId zijn de GUIDs die weergegeven worden bij hetuitvoeren van het Get-AzureRmSubscripion Cmdlet. Het clientId wordtgevuld met het eerder opgeslagen AppPrincipalId en tenslotte heb-ben we de thumbprint van het eerder geregistreerde certificaat nodigom dit op te kunnen halen uit de machine store. (Gebruik geen spa-ties in de thumbprint en denk om het hidden character wat soms aanhet begin of einde van de thumbprint staat bij het kopieren ervan.)

In het tweede deel wordt de authenticatie tegen Azure AD gedaan.Hiervoor worden een aantal classes uit het Microsoft.IdentityModel.Clients.ActiveDirectory package gebruikt. Uiteindelijk krijgen wehier een token terug, wat wordt meegegeven aan een SqlManage-mentClient. Deze class komt uit het Microsoft.Azure.Management.Sqlpackage. Deze class kan gebruikt worden voor management opera-ties op AzureSql servers en databases. Ten slotte wordt deze classdan ook gebruikt om een server aan te maken in de resource groupen uiteindelijk een nieuwe database.

ConclusieIn dit artikel heb ik gedemonstreerd hoe je vanuit C# code je Azure resources kunt beheren. Dit kan op een veilige manier, zonder wacht-woorden op te hoeven slaan in je code of configuratie door gebruik temaken van certificaten. Ook is het via ARM mogelijk om je applicatiezo min mogelijk rechten te geven om zijn taken uit te voeren. Het iseven werk om je applicatie te registeren en authenticatie op basis van

MAGAZINE

16

Page 17: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

CLOUD

een certificaat op te zetten. Echter, wanneer dit eenmaal gedaan iskun je snel en eenvoudig, volledig geautomatiseerd resources beheren.

Ruwe Powershell

ResourceGroupName : DemoLocation : westeuropeProvisioningState : SucceededTags : ResourceId : /subscriptions/4…f/resourceGroups/Demo

PS C:\Users\Henry Been> $scope = "/subscriptions/4…f/resourceG-roups/Demo"

PS C:\Users\Henry Been> New-AzureRmRoleAssignment -ServicePrinci-palName $appPrincipalId -RoleDefinitionName Contributor -Scope$scope

RoleAssignmentId : /subscriptions/4...f/resourceGroups/Demo/pro-viders/Microsoft.Authorization/roleAssignments/9248dbbd-25d0-4ea1-908f-

b82e41d14bacScope : /subscriptions/4…f/resourceGroups/DemoDisplayName : DemoApplicationSignInName : RoleDefinitionName : ContributorRoleDefinitionId : b24988ac-6180-42a0-ab88-20f7382dd24cObjectId : 42dc1e1e-74e0-4d34-b66a-defea55f692cObjectType : ServicePrincipal

PS C:\Users\Henry Been>

Ruwe C#:

var armLocation = "https://management.core.windows.net/";var subscriptionId = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX";var tenantId = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX";var clientId = "0b2b0571-66d8-4e2e-8aa2-af5038a9d2cd";var certificateThumbprint = "XXXXXXXXXXXXXXXXXXXXXXXXXXX";

var aadEndpoint = $"https://login.windows.net/{tenantId}";

var context = new AuthenticationContext(aadEndpoint); ;var certificate = GetCertificate(certificateThumbprint);var credentials = new ClientAssertionCertificate(clientId, certi-ficate);var loginResult = context.AcquireToken(armLocation, credentials);var tokenCredentials = new TokenCloudCredentials(subscriptionId,loginResult.AccessToken);var managementClient = new SqlManagementClient(tokenCredentials);

managementClient.Servers.CreateOrUpdate("Demo", "someuniqueserver-name", new ServerCreateOrUpdateParameters{

Properties = new ServerCreateOrUpdateProperties{

AdministratorLogin = "henry",AdministratorLoginPassword = "Test123test",Version = "2.0"

},Location = "West Europe"

});

PS C:\Users\Henry Been> Connect-MsolService

PS C:\Users\Henry Been> New-MsolServicePrincipal -DisplayName Demo-ApplicationThe following symmetric key was created as one was not suppliedjhbAiJ2DZLvskaR+7p0BYUC68GR3sAHDyZWkwtvECVM=

DisplayName : DemoApplicationServicePrincipalNames : {0b2b0571-66d8-4e2e-8aa2-af5038a9d2cd}ObjectId : 42dc1e1e-74e0-4d34-b66a-defea55f692cAppPrincipalId : 0b2b0571-66d8-4e2e-8aa2-af5038a9d2cdTrustedForDelegation : FalseAccountEnabled : TrueAddresses : {}KeyType : SymmetricKeyId : 4d9a6a02-cda9-42ac-93d7-b6fff3d887d4StartDate : 17-2-2016 13:56:36EndDate : 17-2-2017 13:56:36Usage : Verify

PS C:\Users\Henry Been> $appPrincipalId = "0b2b0571-66d8-4e2e-8aa2-af5038a9d2cd"

PS C:\Users\Henry Been> $certificate = New-ObjectSystem.Security.Cryptography.X509Certificates.X509Certificate

PS C:\Users\Henry Been> $certificate.Import("C:\Users\HenryBeen\OneDrive\SSL Certificaten\armclient.henrybeen.nl.crt")

PS C:\Users\Henry Been> $binaryCertificate = $certificate.Ge-tRawCertData()

PS C:\Users\Henry Been> $base64Certificate = [System.Convert]::To-Base64String($binaryCertificate)

PS C:\Users\Henry Been> New-MsolServicePrincipalCredential -App-PrincipalId $appPrincipalId -TYpe Asymmetric -Value $base64Certifi-cate -Usage verify

PS C:\Users\Henry Been> Get-MsolServicePrincipalCredential -App-PrincipalId $appPrincipalIdcmdlet Get-MsolServicePrincipalCredential at command pipeline posi-tion 1Supply values for the following parameters:ReturnKeyValues:

Type : AsymmetricValue : KeyId : 5bd435d7-10c5-4900-b609-7e53f7bae023StartDate : 18-10-2015 03:40:43EndDate : 17-10-2016 17:55:49Usage : Verify

Type : SymmetricValue : KeyId : 4d9a6a02-cda9-42ac-93d7-b6fff3d887d4StartDate : 17-2-2016 13:56:36EndDate : 17-2-2017 13:56:36Usage : Verify

PS C:\Users\Henry Been> $keyId = "4d9a6a02-cda9-42ac-93d7-b6fff3d887d4"

PS C:\Users\Henry Been> Remove-MsolServicePrincipalCredential -AppPrincipalId $appPrincipalId -KeyIds($keyId)

PS C:\Users\Henry Been> Login-AzureRmAccountEnvironment : AzureCloudAccount : [email protected] : 4ace870a-33ad-44bf-bd3a-faa5ee1af0efSubscriptionId : 4…fCurrentStorageAccount :

PS C:\Users\Henry Been> New-AzureRmResourceGroup -Name Demo -Loca-tion WestEurope

Henry Been

Henry werkt als software architectbij SnelStart. Hij houdt zich bezigmet het applicatie landschap en dearchitectuur van de bij SnelStart ont-wikkelde software. Zijn interesse ligtbij het schrijven van onderhoudbareen veranderbare code.

magazine voor software development 17

Page 18: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

WEB

What are TagHelpers?TagHelpers can be seen as the evolution of HTML helpers which wereintroduced with the launch of the first MVC framework. To provide con-text you have to imagine that with classic ASP the only way you couldautomate the generation of HTML is via custom subroutines. After thatASP.NET came with server controls, with view states as biggest plus,to simulate the look and feel of desktop applications and help with thetransition for desktop developers. But we all know what happens whenwe try to jam squares in to round holes. We had to face the fact thatweb development is nothing like desktop development. To get in linewith proper web development the ASP.NET MVC framework was laun-ched with HTML helpers to automate the HTML output. But HTMLhelpers never really gelled, especially not with front end developersand designers. One of the main pet peeves was that it made youswitch a lot from angle brackets (HTML, CSS) to C# (Razor syntax)during work on views, which made the experience unnecessarily un-comfortable. [MVC 6] wants to address this and some smaller issuesby introducing TagHelpers. More on this here [1]. On the view sidethey totally behave like HTML tags. And this reduces context swit-ching. The easiest way to introduce a TagHelper is to look at the onefor the anchor tag. With the HTML helper this would've been done as:

With the anchor TagHelper this would look like:

Side note: Please note that asp- is just a convention, but more on thatlater.

The output rendered in the browser is the same for both:

Side note: Provided the default route has not been altered.

Danny van der Kraan

This should illustrate that a designer for instance is much better acquainted with the TagHelper syntax as it handles just like plainHTML, as opposed to the HTML helper which is almost like calling amethod in C#.

The hyperlink TagHelper is not the only one provided by [MVC 6]. Let'shave a quick run through and start off by how to actually get the TagHelpers in your project.

Common TagHelpers[MVC 6] comes with a bag of TagHelpers and to add them to yourproject you need to add the following line to the dependencies sectionof the project.json file:

Side note: When you save the file Visual Studio should automatically download and install the appropriate NuGetpackage(s), but if it doesn't then you can also right click onthe project and choose "restore packages" from the contextmenu or use the command "dnu restore" in the developer'scommand prompt from the folder where the solution file resides.

Then you need to make the view aware that you would like to enableTagHelpers. This is an explicit directive, which is the way you want it!Just add this line of code to the top of your view:

Notice how the directive makes use of the glob notation [2]. The firstparameter is the name (or names) of the TagHelper(s) you want to use.By specifying the wildcard (*) you instruct the framework to add allTagHelpers. The second parameter is the assembly name. So herewe give the instruction to add all TagHelpers from the Microsoft.AspNet.Mvc.TagHelpers assembly.

Side note: You could also add this directive to a new Razor fileintroduced with ASP.NET 5 called _ViewImports.cshtml.

MAGAZINE

18

ASP.NET Core 1.0: Goodbye HTML helpersand hello TagHelpers!Synopsis: ASP.NET Core 1.0 [MVC 6] comes with a new exciting feature called TagHelpers.Read on to see why I think we can kiss HTML helpers goodbye. Find the accompanying sourcecode on my GitHub [4]. Please note that MVC 6 will be mentioned in square brackets,because at the moment of writing this it was still called that way, but it is all simply called ASP.NetCore 1.0 now.

Page 19: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

WEB

magazine voor software development 19

Its main purpose is to provide namespaces which all other views canuse. Similar to what the web.config file in the Views folder used to do.You can add this file to any view folder as to have finer granular con-trol over which views have access to what exactly. And it's additive,pretty convenient! You can read more on this file here [6].

Once this line is added to your view you'll have access to the followingpredefined TagHelpers:• Anchor• Cache• Environment• Form• Input• Label• Link• Option• Script• Select• TextArea• ValidationMessage• ValidationSummary

Side note: If you don't see TagHelpers in your IntelliSense youneed to add a reference to "Microsoft.AspNet.Tooling.Razor":"1.0.0-rc1-final" in your project.json file.

Let's briefly run through these Tag Helpers.

AnchorWell we've seen this at its simplest form already:

Just the "asp-controller" and "asp-action" attributes. But the anchorTagHelper has much more to offer.• You can add route parameters by using the "asp-route-" prefix

(example: asp-route-id = @ViewBag.PatientId).• You can use a named route with the "asp-route" attribute• You can force protocols like https by using for example: asp-proto-

col="https" (and if you want to do this for a certain domain you use"asp-host")

• You can link to a specific part of your page by using "asp-fragment"

We'll need a follow up to talk about the anchor Tag Helper separately.

CacheCan be a useful Tag Helper for improving your performance by storingcache entries in local memory. This means that anything that will stopthe host process will cause the cache entries to be lost. This is something to keep in mind when for instance your Azure instancesget scaled. A scale down means losing the cache.

But if you bear this in mind it simply works by wrapping any portion ofRazor View you want and storing that content in an instance of IMemoryCache. The simplest form looks like:

But you can do a lot more cool stuff with this, like having it vary byuser, or by route. I'll treat the cache Tag Helper in detail another time.

FormThe form Tag Helper reads much easier than the form HTML helper

and looks at its most basic like:

The output would be:

Side note: As you can see the Tag Helper automatically rendersan input element to create the anti-forgery token [7].

There are more options, but I'll write about that separately.

InputThe input Tag Helper is one of the form elements and could be usedto replace the HTML helper EditorFor. Imagine the following class:

The input Tag Helper looks like:

This renders as:

The input Tag Helper will be described further another time.

LabelThe label TagHelper is one of the form elements and could be used toreplace the HTML helper LabelFor. Imagine the following class:

The label Tag Helper looks like:

This renders as:

Notice how the label Tag Helper is capable of automatically grabbingthe value of the Name property of the Display attribute. And that is allthere is to the label Tag Helper really.

Link, Script and EnvironmentThe link and script Tag Helper also support globbing[2]. An interestingexample could be:

Page 20: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

WEB

MAGAZINE

20

This tells via globbing and the 'asp-src-include' Tag Helper attribute toinclude all '.js' files in the 'js' of 'wwwroot'. I've thrown 'bootstrap.js','jquery.js' and 'npm.js' in the 'js' folder at 'wwwroot' and therefor itproduces the following output:

Pretty convenient right? You can also exclude files, reference files fromhosted CDN and provide a fallback, and much more. You can evenapply cache busting via the 'asp-append-version' attribute. More onthese Tag Helpers in a seperate article.

Side note: Actually, when you use it exactly like the exampleabove you'll get an error, because bootstrap needs jQuery.You'll want to reference hosted CDNs and provide fall-backs,for example:

But as I've written above, this deserves a separate article.

Let's focus on the environment Tag Helper now instead. This Tag Hel-per works really well with the script and link Tag Helpers and is there-fore included in this paragraph. With ASP.NET Core 1.0 you can setthe environment to different stages: Development, Staging, and Pro-duction. And with the environment Tag Helper we could include all theunminified .js files in development, while using the minified versions instaging/production. Like this:

I've seen it most commonly used like this and I currently only use thisTag Helper for this reason.

Select and OptionA select is not really useful without options, so therefor they are des-cribed together in this section. A select will render as a drop down listand is the equivalent of the HTML helper 'DropDownListFor'. So wehave 'SomeModel' with 'SomeString' from our example. And in the'Index' method of the 'HomeController' we add some options to aViewBag property, like this:

You could use this Tag Helper as follows:

Which would render to the browser as:

And if the property at the asp-for is of type IEnumerable, then the TagHelper would automatically render a multi-selectable dropdown.

TextAreaThe text area Tag Helper is the replacement of the HTML helper 'Tex-tAreaFor' and basically works the same as the input Tag Helper. Toshow how it works I've expended our 'SomeModel' with the property'SomeLargeString' and a 'MaxLength' attribute:

You simply write the tag in HTML as follows:

This outputs the following HTML to the browser:

It plays along nicely again with the attributes like 'MaxLength', 'Re-quired', etc., providing adequate attributes in HTML as can be seen inthe rendered HTML above.

ValidationMessage and ValidationSummaryThe textarea Tag Helper is capable of providing its own validation at-tributes, like 'data-val-maxlength-max', but it is also possible to expli-citly set the validation with the validation message TagHelper:

SomeString could have the 'Required' attribute, like so:

The span will actually render to the browser as:

Don't forget to change the post method in the HomeController:

Page 21: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

WEB

magazine voor software development 21

Just make a simple Succes.cshtml for when the state of the model isvalid. And when the required SomeString is not provided on the postthe same page will return with the span rendered as:

But most of the time is prettier to summarize all validation messagesand that is where the validation summary Tag Helper comes in:

You simply add the 'asp-validation-summary' to a div tag and it works.The attribute requires a ValidationSummary enumeration which couldbe 'All', 'ModelOnly' or 'None'. Why you would ever want to choose'None' is beyond me, just don't add a validation summary then! Butthe 'ModelOnly' is to only include validations on model level and 'All'is to include both model level and property level. It will render as:

And when SomeProperty is not provided while it has the 'Required' attribute it'll render as:

These were the provided TagHelpers by [MVC 6], now let's see howyou can create one yourself!

Custom TagHelpersYou can expand existing HTML elements with a TagHelper or you canmake your own TagHelper completely from scratch. This practice iscalled 'authoring TagHelpers' [3]. The first kind will function as simplyanother attribute on the HTML element like we saw with the HTMLHelpers 'asp-action' and 'asp-helper' at the anchor tag. The processof making your own TagHelper is very similar in both cases. Let's firstcreate a TagHelper that you can use as attributes.

AttributesAs a nice short example we can have a span tag that you could pro-vide a message and a level for how big you want that message dis-played, like this:

To make this HTML work I wrote the following code which we'll walkthrough:

First of all you need to derive from the class TagHelper to make a Tag-Helper (you could theoretically also implement ITagHelper).With the HtmlTargetElement attribute above the MessageTagHelperclass you can specify to which HTML element(s) this TagHelper appliesto. The Attributes property is a comma separated list with which youcan make certain attributes required. I wanted the MessageValue pro-perty required as can be seen in the code above. You can decorate theproperties with the attribute HtmlAttributeName to give them a clearname in HTML.

Side note: This attribute is not required as the property's namein camel case will be converted to 'lower kebab case' as a con-vention (so for example: "message-value"). But in this exam-ple we adhere to the 'asp-' convention for TagHelpers withoutmessing up the names of the properties.

Now you need to override either the 'Process' method or the 'Pro-cessAsync' method if you expect to handle large files or something.This is an extremely simple TagHelper so the sequential variant will bemore than sufficient.You get passed along the TagHelperContext and the TagHelperOutputparameter. The TagHelperContext contains all kinds of informationabout the element this TagHelper targets. So in our case the concer-ning span element. I didn't need the parameter in this example, butyou'll probably need it as the TagHelper becomes more complex. TheTagHelperOutput parameter is used all the time as it is used to trans-form, append and remove the HTML.

The TagName is changed to "div" (to be honest this is just because theh tags are block elements and the span tag is an inline element). TheTagMode is set to StartTagAndEndTag to enable you to use the spanin HTML as a self-closing element. Then you see some code to dealwith the given level, nothing fancy. At the end you can see the contentappended to the output's 'Content'. You also have 'PreContent' and'PostContent', which I didn't need for this simple example. But ex-ploring the TagHelperOutput parameter is really going to help youmake complex TagHelpers.

When we run this the actual HTML rendered will be:

As have been said you can also create HTML elements completelyfrom scratch.

ElementsYou can also create entire new HTML tags. For this example we'll have

Page 22: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

WEB

MAGAZINE

22

a look at Bootstrap styled panels:

It would be better to be able to write:

It is more in line with HTML5's semantic way of coding the layout. Itreads better. So let's make it happen. All we need is the following codereally:

Let's go through the code and start at PanelTagHelper. The TagHel-per suffix is discarded and the rest is used as the name for the Tag-Helper. So in this case the HTML element is called "panel". We use theRestrictChildren attribute above the class declaration to restrict thetypes of HTML elements that can be used in between the 'panel' tag.

Notice for instance how it says 'panel-header'. Why is that not 'panelheader', because the class's name is PanelHeaderTagHelper?Well like properties, which is said earlier, class names also follow thelower kebab case. And because we didn't define another name, it willgo by default.

Side note:TagHelper suffix is not required but considered a bestpractice convention.

This time the 'ProcessAsync' method is overridden. It is still not necessary, but I wanted to show you what it looks like. There we use'TagName' to change the tag to a 'div' tag. And we make sure 'panel'is in the class attribute, so Bootstrap's 'panel' styling can kick in.And you can see this basically in all the ProcessAsync methods. Justchanging the class to the appropriate one (panel-header, panel-body,panel-footer). Point of interest though is the HtmlTargetElement attri-bute. It is there to make sure this TagHelper is used on the right HTMLelement. It has a ParentTag attribute to tell that it only applies if the'panel-header' (or body/footer) is in between the 'panel' tag. But thisis unfortunately not enough. See header, body and footer all apply tothis rule and we would end up with divs that have all three classes. Sowe also need to tell exactly what HTML tag the TagHelper applies to,to prevent this from happening.

Side note: You can find much more (and better) TagHelpersamples on Dave Paquette's GitHub [5].

ConclusionI hope we can all agree that the ideal webpage is written in nothing butHTML and Javascript. TagHelpers remove awkward C# code from ourRazor Views making it look more like straight up HTML. This is espe-cially great for the non-programmers, like designers, who just want todesign great looking pages in HTML and CSS without being tangledin webs of backend code. But also for the full-stack developer whodoes enough context switching as is. Thank you for reading and checkout the source code for this article on GitHub [4].

Links• TagHelpers vs HTML

helpers:http://docs.asp.net/projects/mvc/en/latest/views/tag-hel-pers/intro.html#tag-helpers-compared-to-html-helpers

• Glob notation: https://en.wikipedia.org/wiki/Glob_%28program-ming%29

• Authoring TagHelpers: http://docs.asp.net/projects/mvc/en/la-test/views/tag-helpers/authoring.html

• My GitHub: https://github.com/dannyvanderkraan/taghelpers• Dave Paquette's TagHelper samples: https://github.com/dpa-

quette/TagHelperSamples• _ViewImports.cshtml: http://www.exceptionnotfound.net/the-vie-

wimports-cshtml-file-setting-up-view-namespaces-in-mvc-6/• Anti-forgery token:

http://blog.stevensanderson.com/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/

Danny van der KraanDanny van der Kraan is a passio-nate software engineer with a widearea of interest. From desktop ap-plications with WPF MVVM andMSSQL to distributed architectureswith NServiceBus, Azure Storageand ASP.NET MVC. Currently wor-king for Sound of Data with cutting

edge technologies. Follow these adventures on the blog:https://dannyvanderkraan.wordpress.com/

Page 23: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

.NET Fanie Reijnders

Nuget 3.0 supports a brand new format for the packages manifest,called project.json and it brings way more flexibility and power. Starting from Visual Studio 2015, several project types are already utilizing this technology like Universal Windows Platform managedapps, Portable Class Libraries and ASP.NET Core applications.Although traditional project types don’t (yet) support all the functiona-lity of project.json, they can still leverage at least some advantagesthat this new package format brings: No changes to .csproj files (preventing merge conflicts), no need to run nuget update (by using the* notation), transitive restore (allowing just the top level dependenciesto be defined) and P2P dependency flow, for allowing a top level appto always pick up dependencies from class libraries it depends on;without explicitly installing them.

Transitioning from old to newLet’s take a typical class library with a dependency on the NewtonsoftJson package with the following packages.config:

Adding this reference means that this packages added an explicit reference to newtonsoft.json.dll in the .csproj file located in the net45folder. The side-effects are that it allows one to edit the packages.con-fig file and re-target the application without re-installing the package.

Making the changeBefore continuing, it is advised to make a backup of the packa-ges.config file so you can easily roll back if something goes wrong.

1. From the Package Manage Console, uninstall the package:

Uninstall-Package newtonsoft.json –Force

2. Create a project.json file on the root level of the project with thefollowing content:

Note: I added the Newtonsoft.json dependency, it can be addedthrough editing the file, and relying on intellisense from the editor, orby using the standard Nuget GUI.

3. Reload the solution (there is currently a bug where switching from packages.config to project.json requires a reload of the project).

4. Build or restore packages (Right Click on the Solution level). The project will now use project.json instead and the .csproj file will bea bit cleaner:

Note: You cannot see references in the .csproj file, the referencesget added at build time, and do not show up in the project. You cansee them in the references tree in Visual Studio with a Nuget icon.

It’s important to know that project types relying heavily on content packages and XDT transforms won’t work with project.json at the moment. •

magazine voor software development 23

Migrate a .csproj frompackage.config to project.jsonAs we all know: Nuget is awesome. Until recently, on Nuget 2.0; it uses a “packages.config” file within ourC# projects and contains a list of all dependent packages for the project. Although this little XML file is quitehandy, things tend to go wrong when more complex scenarios that presents itself. In a C# projects, it mightmean changing the .csproj file and sometimes (also) the app.config/web.config file(s) as well as other files.

<?xml version="1.0" encoding="utf-8"?><packages><package id="Newtonsoft.Json" version="7.0.1" targetFra-

mework="net45" /></packages>

<ItemGroup><Reference Include="Newtonsoft.Json, Version=7.0.0.0,

Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processo-rArchitecture=MSIL">

<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>

<Private>True</Private></Reference>

<Reference Include="System" /><Reference Include="System.Core" /><Reference Include="System.Xml.Linq" /><Reference Include="System.Data.DataSetExtensions"

/><Reference Include="Microsoft.CSharp" /><Reference Include="System.Data" /><Reference Include="System.Net.Http" /><Reference Include="System.Xml" />

</ItemGroup><ItemGroup>

<Compile Include="Program.cs" /><Compile Include="Properties\AssemblyInfo.cs" />

</ItemGroup>

{"dependencies": {

"Newtonsoft.Json": "7.0.1"},"frameworks": {

"net45": { }},"runtimes": {

"win": { }}

}

<ItemGroup><Reference Include="System" /><Reference Include="System.Core" /><Reference Include="System.Xml.Linq" /><Reference Include="System.Data.DataSetExtensions" /><Reference Include="Microsoft.CSharp" /><Reference Include="System.Data" /><Reference Include="System.Net.Http" /><Reference Include="System.Xml" />

</ItemGroup><ItemGroup>

<Compile Include="Program.cs" /><Compile Include="Properties\AssemblyInfo.cs" />

</ItemGroup>

Page 24: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

IOT Roel Hans Bethlehem

What do you need:• Hyper-V for Virtualization• The ISO for Ubuntu 14.04 LTS• Visual Studio Code (no need to download as we are using an extra

repository to install it using the package manager apt-get)

I used the x64 version of Ubuntu so I will need the same x64 versionof Visual Studio Code. I assume you have set up Hyper-V and downlo-aded the ISO for Ubuntu. I am also assuming that you have set up anexternal switch so your virtual machine can connect to the internet. If not you can set it up in the virtual switch manager. Mine is configu-red as an external network. In effect the VMs will get an ip addressfrom my router and this enables them to use the internet.

Steps:1. Create a new VM in Hyper-V using the wizard2. Specify name and location of the virtual machine (VM)3. Specify the newest VM format. I have not tried with earlier formats4. Assign memory. I just give it 4 GB but you could probably do with

less.5. Assign networking. I have an external virtual switch so I can connect

the VM to the internet. This is necessary for the package managerapt-get to be working and we also want to be able to use npm, thenode.js packet manager.

6. Create a new virtual harddisk. 20 GB should be plenty.7. Specify the path to the Ubuntu 14.04 LTS iso in installation

options.8. Finish the wizard.Now the virtual machine is created, go into settings.

Bump up the number of processors:

I have set 4 processors as I have plenty of (virtual) processors on anAMD FX8320. This CPU is an octacore. The reason to assign extraprocessors is that I could not get video acceleration working onUbuntu in Hyper-V. If you just have one processor the Ubuntu desktopperforms quite slowly.Now we also need to set some boot options as otherwise Ubuntu willnot boot. We need to disable secure boot (I think this only applies to2nd generation VMs):

Okay now we are done let’s boot Ubuntu by starting the VM. Chooseinstall Ubuntu.

Now the installer boots up and just accept the defaults but make sureyou choose the correct timezone and set the correct keyboard set-tings. For username set it to something you can remember and set itto login automatically.

Now Ubuntu will install and get yourself some more cafeïne.

Restart and after pressing enter you should be greeted with theUbuntu desktop.

MAGAZINE

24

Setting Up Visual Studio Code OnUbuntu 14.04 Lts In Hyper-VSince I like programming with the Raspberry Pi and also like Microsoft Visual Studio I thoughtit would be nice to set up a virtualized Ubuntu 14.04 LTS with Visual Studio Code. This can thenserve as the development platform for my Raspberry Pi since it has support for node.js andPython.

Page 25: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

magazine voor software development 25

IOT

Now we will need to do a few things.We will need to update Ubuntuto the latest version We will need to install extras to enable some extra functionality. See: https://technet.microsoft.com/en-us/library/dn531029.aspxWe need to fix the video settings so we can run full screen in Hyper-V

1. Update Ubuntu.Open a terminal in Ubuntu. If you are not familiar with Ubuntu just pressthe button in the upper left corner and type terminal

Click terminal in applications. Then type the following:

sudo apt-get updatesudo apt-get upgrade

This will update Ubuntu.

2. Install extensions for the Hyper-V on the virtual machine.In the same terminal type:

sudo apt-get install –install-recommends linux-virtual-lts-vividsudo apt-get install –install-recommends linux-tools-virtual-lts-vividlinux-cloud-tools-virtual-lts-vivid

3. Fix the video settings. Since we want to develop we need to run full screen. To do this weneed to set the video manually as display settings in Ubuntu cannotdetect the correct settings. In the same terminal type (i am using nanosince it is more friendly as vi):

sudo nano /etc/default/grub

Locate the line that reads:GRUB_CMDLINE_LINUX_DEFAULT=”quiet splash”

And change it to (in my case 1920×1080 is the highest my monitor canhandle):

GRUB_CMDLINE_LINUX_DEFAULT=”quiet splashvideo=hyperv_fb:1920×1080”

Press ctrl-x and say Y to save your settings. Now update grub by “typing this in the terminal, then reboot:

sudo update-grubsudo reboot

You should now be able to run your hyper-v vm with Ubuntu in fullscreen. Now we should be able to install some Visual Studio Codegoodness. After the reboot open up the terminal again (taken fromhttp://askubuntu.com/questions/616075/how-to-install-visual-studio-code-on-ubuntu).

sudo add-apt-repository ppa:ubuntu-desktop/ubuntu-makesudo apt-get updatesudo apt-get install ubuntu-make

Then install Visual Studio Code:

umake ide visual-studio-code

Now Visual Studio Code will be installed and an icon will be added inthe launchbar for Visual Studio.Fix problematic node nodejs reference

ln -s /usr/bin/nodejs /usr/bin/node

See: http://stackoverflow.com/questions/26320901/cannot-install-no-dejs-usr-bin-env-node-no-such-file-or-directoryYou are ready to go now. •

Roel Hans Bethlehem

My name is Roel Hans Bethlehemand I am working as a SharePoint /.NET Architect for the Nederland-sche Bank in Amsterdam. I live inHilversum with Claire and my kidsKim and David. We have a cat

Shadow and a rabbit called Emma.

Page 26: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

ALM

method:analyze* levert AnalyzerForLanguage en AnalyzeControlFlowop. Zoeken op arg:x? geeft resultaten als x1, x2 or xx (allemaal gevonden in de Roslyn code!).

Fig.2: De resultaten van een eenvoudige keyword search

Fig.3: Beschikbarefilters tijdens hetzoeken

Code SearchCode Search is een nieuwe feature binnen Visual Studio Team Services die je hierbij helpt. Code Search stelt je instaat om in éénkeer door meerdere repositories heen te zoeken. Code Search is beschikbaar als een gratis extension die je kunt installeren vanaf de Visual Studio Marketplace (https://marketplace.visualstudio.com/items/ms.vss-code-search). Nadat je deze extension hebt geïnstal-leerd kun je de search box in VSTS gebruiken om een nieuwe codesearch te starten. Zelf gebruik ik Code Search steeds vaker. Ik hebbijvoorbeeld een Samples project aangemaakt waarin ik onder anderede source code van Roslyn, ASP.NET, .NET Framework en andereopen source projecten heb gezet. Hier kun je daarna eenvoudig door-heen zoeken als je wilt weten hoe iets werkt.

Fig.1: Code Search is te installeren vanaf de Visual Studio Marketplace

Figuur 2 laat de zoekresultaten van het keyword analyzer zien als jedoor de Roslyn code base heen zoekt. De zoek resultaten zijn gegroepeerd per bestand. Op de pagina zie je meteen de inhoud vaneen file en wordt het keyword waarop je zoekt netjes gehighlight.Zoeken op keyword is nog niet zo heel spannend. De echte krachtvan Code Search zie je pas als je de ingebouwde filters gaat gebrui-ken. Figuur 3 laat zien welke filters je allemaal hebt. Zoeken opclass:Analyzer bijvoorbeeld beperkt de resultaten tot alle plekken inde Roslyn code waar een class genaamd Analyzer is gedefinieerd.Zoek je op method:analyze* vind je alle resultaten van methods diebeginnen met het woord analyze. Het wildcard teken * matched allekarakters terwijl een ? één karakter matched. Dus zoeken op

Zoeken door code. Hoe spannend kan dat zijn? Het klinkt misschien niet spannend maar tochis het iets wat we als ontwikkelaars allemaal doen. Zoeken naar een bepaalde method om tekijken hoe iets werkt, een bestaande oplossing voor je probleem proberen te vinden of eenvoorbeeld van hoe je een API gebruikt. In Visual Studio kun je vrij eenvoudig door je open solution heen zoeken. Maar wat als je het zoeken naar een hoger niveau wilt tillen? Stel dat jeverder wilt kijken naar jouw project en wilt weten of iemand in je organisatie een bepaald probleem heeft opgelost of een API gebruikt. Hoe zou je dat aanpakken?

Wouter de Kort

Code search in VisualStudio Team Services

MAGAZINE

26

Page 27: SDN Magazine 128 · package.config to project.json Fanie Reijnders 24 Setting Up Visual Studio Code On Ubuntu 14.04 Lts In Hyper-V Roel Hans Bethlehem 26 Code search in Visual Studio

ALM

magazine voor software development 27

Naast dat je dus kunt zoeken op code elementen, kun je ook filterenop een specifiek project of pad. Bijvoorbeeld, zoeken opbasetype:IDisposable path:*Test* geeft alle elementen terug die IDis-posable in de class hiërarchie hebben en ergens in het pad het woordTest. Je kunt ook meerdere statements combineren met de bekendeoperators AND, OR en NOT. Als je bijvoorbeeld zoekt op basetype:IDisposable NOT path:*Test*, worden juist alle resultaten met ergensTest in het pad genegeerd. Je kunt al deze filters zelf invoeren maar jekunt ook de checkboxes gebruiken in de interface. Het filter wordt danvoor je opgebouwd. Momenteel begrijpt Code Search C#, C en C++.Andere talen wordt nog aan gewerkt.

Tot slotMet Code Search kun je dus eenvoudig door meerdere repositorieszoeken zolang je maar lees rechten hebt op een repository. Microsoftzelf gebruikt dit ook. Zij hebben daarom als beleid dat alle code dooriedereen te doorzoeken is. Je kunt voorstellen wat een enorme hoe-veelheid aan code dat moet zijn en hoe handig het is om daar zo sneldoorheen te kunnen zoeken. Een voorbeeld waarin ze dat gebruikthebben is bij het hernoemen van Visual Studio Online naar Visual Stu-dio Team Services.

Code Search is nu al beschikbaar voor VSTS en zal ook in een van deupdates voor on-premises verschijnen.

Veel zoekplezier! •

Wouter de Kort

Wouter de Kort werkt als PrincipalConsultant Microsoft bij Ordina. Hijleidt hier het Application LifecycleManagement Competence Center.Wouter helpt organisaties omvoorop te lopen op technisch vlak.Hij richt zich hierbij vooral op ALM,Agile en DevOps. Wouter heft eenpaar boeken geschreven en is een

van de Microsoft ALM Rangers. Je kunt hem vinden op Twitter(@wouterdekort), op zijn blog: http://wouterdekort.com en op deverschillende conferenties waar Wouter spreekt.

Building on the exceptional success of previous years, Global Azure Bootcamp 2016 (#GlobalAzure) is afree one-day training event, taking place on the 16th of April 2016 in several venues worldwide, driven bylocal Microsoft Azure community enthusiasts and experts. It consists of a day of sessions and labs basedon the Microsoft Azure Readiness Kit or custom content. The event has been originally designed by 5 Microsoft Azure MVPs in order to benefit the local community members and teach essential MicrosoftAzure skills and know-how. While supported by several sponsors, including Microsoft, the event is completely independent and community-driven. http://global.azurebootcamp.net/

“In our first year we had 9000 servers rendering 3D images. In 2014 we’ve smashed that numberwith 17.000 cores doing diabetes research. The enthusiasm shared by people participating in thisone day global event is truly fantastic!” - Maarten Balliauw, global event organizer

Global Azure Bootcamp: 16th ofApril 216 at a location near you!