ppedv Team Blog: Breadcrumb-Ansicht in SharePoint 2013

Um in SharePoint 2013 die vielen Menschen liebgewonnene Breadcrumb-Ansicht oder anders ausgedrückt Brotkrümel-Ansicht anzuzeigen, wird im folgenden Artikel die Vorgehensweise beschreiben.

Es empfiehlt sich den SharePoint Designer 2013, nachfolgend SDP 2013 genannt, hierfür zu benutzen.

Hinweis: Damit die Nachfolgenden Schritte funktionieren, ist es zuvor notwendig, die nachfolgenden als Screenshot aufgeführten Features, einzuschalten. Darüber hinaus muss auch eine entsprechende Website-Struktur erstellt worden sein (Untersites) und die Navigationseinstellungen bearbeitet worden sein (Unterwebsites anzeigen aktivieren)

1. Homepage aufrufen (Website der obersten Ebene), Features aktivieren

Einstellungen -> Websiteeinstellungen -> Websitesammlungsverwaltung -> Websitesammlungsfeatures -> SharePoint Server-Veröffentlichungsinfrastruktur

clip_image002

Einstellungen -> Websiteeinstellungen -> Websiteaktionen -> Websitefeatures verwalten -> SharePoint Server-Veröffentlichung

clip_image004

Hinweis: Das SharePoint Server-Veröffentlichung Feature muss auf jeder Unterwebsite aktiviert werden. Des Weiteren ist die Navigationsvererbung einzuschalten.

2. Nachdem die Verbindung im SPD 2013 hergestellt worden ist, wird im Navigationsbereich links unter Websiteobjekte der Punkt Gestaltungsvorlagen aufgerufen.

3. Standardmäßig wird die seattle.html Masterpage verwendet. Hier gilt es die seattle.html aufzurufen, nicht die seattle.master.

Nun sucht man im Code am besten mittels Tastenkombination Strg + F nach „ms-breadcrumb-box

clip_image006

4. Hier wird die Eigenschaft unter „Visible“ statt false auf „true“ gesetzt.

5. Danach wird in der Code-Ansicht nach der passenden Stelle gesucht, an der die folgenden zwei Code-Zeilen eingefügt werden:

<!--MS:<asp:sitemappath runat="server" sitemapproviders="SPSiteMapProvider,SPXmlContentMapProvider" rendercurrentnodeaslink="false" hideinteriorrootnodes="true">-->

<!--ME:</asp:sitemappath>-->

In meinem Beispiel habe ich die Breadcrumb-Ansicht unterhalb des Titels der jeweiligen Webseite eingefügt. Der Bildausschnitt zeigt, an welcher Stelle es vorgenommen werden muss.

clip_image009

Jetzt wird die Masterpage gespeichert und die Website aktualisiert. Das fertige Ergebnis sieht dann folgendermaßen aus:

clip_image012

Unterhalb des Titels wird als Pfad angezeigt, welche Unterwebsites geöffnet wurden.

Klaus Aschenbrenner: A ever-increasing Clustered Key value doesn’t scale!

(Be sure to checkout the FREE SQLpassion Performance Tuning Training Plan, where you are getting week by week via email all the essential knowledge you need to know about performance tuning on SQL Server.)

You know all the best practices how to choose a Clustered Key value? A good Clustered Key value should have the following 3 properties:

  • Narrow
  • Static
  • Ever Increasing

Let’s have a more detailed look on all 3 properties, and why an ever increasing value doesn’t really scale in SQL Server.

Narrow

A Clustered Key value should be as small as possible. Why? Because it takes space, and the Clustered Key Value also serves a logical pointer in the leaf level in every Non-Clustered Index. If you have a very wide Clustered Key value, you also deal with larger Non-Clustered Indexes. If you have defined a Non-Unique Non-Clustered Index (which is normally the case), the Clustered Key value is also part of the navigation structure of your Non-Clustered Index. Therefore the overhead in your index gets very large. And our goal is to minimize overhead on our index pages. Overhead that we have to pay in the physical storage, and also in the Buffer Pool, where SQL Server caches the read index pages from storage.

Normally you choose a technical key value (like INT/BIGINT data type) instead of a natural key value. I have already seen over the years Clustered Key value lengths of 100 bytes and more (combinations of LastName, FirstName, SocialSecurityNumber, etc.). Believe me – you are just waisting memory! You don’t have to do that. Choose a technical key, and you are fine.

Static

Because the Clustered Key value is replicated in every Non-Clustered Index, your Clustered Key value should never ever change! Otherwise SQL Server has to maintain transparently in your UPDATE Execution Plan EVERY Non-Clustered Index that you have defined on your table. You are again just introducing additional computing overhead that you don’t need. Use your CPU cycles for more other important stuff. As you know, natural key values can change (like a LastName column, when you get married).

A technical key value (like an INT IDENTITY) can’t change (by default). Therefore the logical pointer (in the form of the Clustered Key value) in all your Non-Clustered Indexes remains stable - without any need to change them – forever!

Ever Increasing

And the 3rd final important property of a “good” Clustered Key value is that the chosen column should give you ever-increasing values. Why? Because you are always adding additional records at the end of your Clustered Index, and therefore you are avoiding expensive Page Splits (regarding CPU cycles, and Transaction Log overhead) and Index Fragmentation. In 99% of all cases you will be fine with an ever-increasing value like an INT IDENTITY column, but there are some scenarios, where this approach can lead to serious scalability problems. Imagine you have a workload, where a lot of different users are inserting permanently into the same table with an ever-increasing Clustered Key value. Just think a second about about Logging/Auditing tables.

Let’s have a more detailed look on what happens internally in SQL Server, when you reading and writing pages in memory. When SQL Server accesses certain memory structures (like pages that are stored in the Buffer Pool), these memory accesses must be synchronized among multiple threads. You can’t write concurrently to the same page in memory. When a thread writes to a page, some other thread can’t read the page at the same time. In traditional concurrent programming you solve that problem with Mutexes - like a Critical Section. Certain code paths are just mutually exclusive. A Latch in SQL Server is almost the same as a Critical Section. And latches are used to synchronize threads/queries among each other. Every time when you read a page, the worker thread has to acquire a Shared Latch (SH), every time when you write a page, the worker thread has to acquire an Exclusive Latch (EX). And both latches are incompatible to each other.

When you now perform an INSERT statement, the worker thread exclusively latches the page where the INSERT statement occurs. In the mean time no one else can read and write from/to this page. With an ever-increasing Clustered Key value this approach doesn’t really scale, because you are just inserting your records at the end of your Clustered Index. Therefore your parallel threads/queries are contending about an Exclusive Latch on the same last page in your Clustered Index. As a side-effect SQL Server executes your INSERT statement serially – one INSERT after the next one. You have hit the famous Last Page Insert Latch Contention. Let’s have a look at the following picture.

Last Page Insert Latch Contention

With the best practice of an ever-increasing Clustered Key value you have a single hotspot at the end of your Clustered Key. The smaller your records are, the more contention you are introducing here. How can you solve that problem? Easy: spread your INSERT statements across the whole B-Tree structure of the Clustered Index. There are various approaches how you can achieve that:

  • Use a random Clustered Key value (like a UNIQUEIDENTIFIER). But be aware of the side-effects: larger logical pointer in EVERY Non-Clustered Index, Page Splits…)
  • Implement Hash Partitioning, if you are using the Enterprise Edition of SQL Server.
  • Eliminate latching through the use of In-Memory OLTP, that is part of SQL Server 2014.
  • Use a so-called Reverse Index. Unfortunately SQL Server doesn’t provide you that kind of index out-of-the box, like Oracle. But you can implement it at your own

Summary

At 99% you will be fine with a narrow, static, and ever-increasing Clustered Key value like an INT IDENTITY data type. But in some rare scenarios where you need a huge amount of parallel INSERT statements (like Logging/Auditing tables), you can hit the Last Page Insert Latch Contention with that approach. If you hit that specific problem, you have to leave your comfort zone, and you have to make sure that you spread the INSERT statements across your whole B-Tree structure. You are mainly fighting against a limitation of how multi-threaded access happens in a traditional B-Tree structure.

I hope that I have given you with that blog posting a good insight, why ever-increasing Clustered Key values can hurt the scalability of your tables.

If you are more interested in how to choose the right Clustered Key Value, I’m also offering a 1-hour long training video through the SQLpassion Online Academy.

Thanks for reading!

-Klaus

ppedv Team Blog: TSQL - Der bessere Replace

Ab und zu sieht man den Wald vor lauter Bäumen nicht. Dieses Mal stand ich vor der Aufgabe aus einer Spalte bestimmte Werte zu ersetzen. Die Liste der zu ersetzenden Werte war doch etwas länger. Mit einem simplen Replace komme ich nicht besonders weit, da sich ja nur ein Wert ersetzen lässt.  Grübel grübel.. Doch es ist ganz simpel.

Das Prinzip:

Wir weisen einer Variablen einen per Replace bereinigten Wert zu.  Anschliessend wird auf das Ergebnis wiederum ein weiterer Replace angewendet (mit einem anderen zu ersetzenden Wert) und dann wiederum der Variable zugewiesen. Das machen wir solange bis wir alle zu ersetzenden Werte durch haben.  Das geht pfeilschnell.

Das ganze packen wir noch in eine Funktion und schon haben wir einen besseren Replace:

CREATE FUNCTION  dbo.BetterReplace (@str NVARCHAR(4000))
RETURNS nVARCHAR(4000) AS
BEGIN
    SET @str = REPLACE (@str,'>',' ')
    SET @str = REPLACE (@str,';',' ')
    SET @str = REPLACE (@str,'&',' ')
    SET @str = REPLACE (@str,':',' ')
    SET @str = REPLACE (@str,'<',' ')
    SET @str = REPLACE (@str,'/',' ')
    SET @str = REPLACE (@str,'\',' ')
    SET @str = REPLACE (@str,',',' ')
    SET @str = REPLACE (@str,'*',' ')
    SET @str = REPLACE (@str,'^',' ')
    SET @str = REPLACE (@str,'ü','ue')
    SET @str = REPLACE (@str,'ä','ae')
    SET @str = REPLACE (@str,'ö','oe')
    SET @str = REPLACE (@str,'"',' ')

  RETURN @str    
END

Zum Beispiel:

declare @str as varchar(100)
set @str='<Tel>+49\8677-98890'

select dbo.BetterReplace (@str)

Ergebnis:

Tel +49 8677-98890

Einfach und wirkungsvoll!

ppedv Team Blog: Open Source: Plötzlich spielt es eine Rolle

Vor rund zwei Jahren habe ich hier im Blog eine Diskussion losgetreten. Völlig frustriert von der miesen Qualität diverser Bibliotheken und fehlender Dokumentation habe ich Dampf abgelassen. Die Aussage: “Es ist mir scheißegal, ob Open Source oder nicht.”

Im Bezug auf die aktuellen Geschehnisse um OPENSSL und den #heartbleed Bug muss ich meine Meinung revidieren. Es ist plötzlich wichtig #OPENSOURCEFREE auf das Produkt-Paket gedruckt zu bekommen. Um es klar zu sagen, dies war kein Einzelfall:

  • Heartbleed, unentdeckt für ca 2 Jahre, schlimmster Sicherheitsunfall in der Geschichte des Internets
  • GnuTLS blieb 10 Jahre unentdeckt
  • Eine fehlende Codezeile im Random Number Bug über 2 Jahre
  • TCP-32764 Backdoor, dessen Urheber bis heute unklar ist

Damit gilt das oft zitierte Statement als widerlegt. In der Wissenschaft reicht ein Negativbeweis. Die Diskussion über Open Source als Sicherheitsrisiko, speziell im Unternehmenseinsatz, ist über 10 Jahre alt, wird aber von den Verfechtern negiert.

"Weil aber Open Source die Offenlegung des Quellcodes bedeutet, können Anwendungen von allen Nutzern ständig weiterentwickelt werden. Auch Fehler lassen sich so meist schneller beheben."

"Der Vorteil von Open Source: Schadsoftware, Bugs oder Sicherheitslücken können in der Regel schneller entdeckt werden. Es reicht allein der Verdacht, und Tausende von EntwicklerInnen nehmen den betreffenden Code ganz genau unter die Lupe", sagt Grote. Die größere Gefahr bestehe vielmehr in den unfreien Komponenten, etwa proprietären Modemtreibern oder Firmware, die meist von den Herstellern kommen und deren Sicherheit niemand überprüfen kann."

Nun stehen zwei Konzepte gegenüber: Open Source und Closed Source. Warum ich glaube, dass Closed Source die bessere Wahl sein kann:

Kosten

Es wird argumentiert, dass bei Open Source die Lizenzkosten wegfallen. Das Beispiel der Stadt München hat bewiesen, dass man mit mehr finanziellem Aufwand ein qualitativ weniger hochwertiges Ergebnis erreichen kann - bei höherem zeitlichem Aufwand. Open Source kann nur seriös eingesetzt werden, wenn das Know-how und die Ressourcen vorhanden sind, den Code zu pflegen. Niemals kann man sich darauf verlassen, dass jemand für immer und gratis seine Bibliothek weiter pflegt oder das jemand ganz automatisch mit Freude und völlig unentgeltlich diesen Job übernimmt. Persönlich schmerzlich erfahren mit dotnetopenauth.

Sicherheit

Ganz generell gesprochen gibt es keinen schlüssigen Zusammenhang zwischen Sicherheit und Open Source. Ein Vier-Augen-Prinzip erhöht die Sicherheit in jedem Softwareprojekt, allerdings ist es auch ein Leichtes, in ein Open Source-Projekt Programmierer einzuschleusen, die andere Ziele verfolgen. Dabei hat sich gezeigt, dass die Entdeckung von Sicherheitslücken über Parsing Tools  und nicht per Code-Analyse erfolgte.

Verantwortung

Der letzte Punkt ist mir erst in den letzten Tagen so richtig klar geworden. Niemand übernimmt die Verantwortung. Gerade in einem Land wie Deutschland, in dem sich jeder gegen jedwede Risken versichert, in dem unglaublicher Aufwand getrieben wird den kleinsten Parksünder dingfest zu machen, kann es sich eigentlich niemand leisten, nicht zu wissen, wer eigentlich Schuld trägt.

Das ist sowohl rechtlich in Fragen der Gewährleistung als auch gesellschaftlich ein unhaltbarer Zustand.

Stellen Sie sich mal vor eine Airline würde Metallteile verbauen, die sie auf der Straße findet.  Dann hätten wir nicht nur eine MH370, sondern jeden Tag zehn. Verantwortungslos.

Fazit

Open Source wurde immer durch Gebrauch des englischen Begriffs "free" mit gratis verwechselt. Nachdem dieser Irrtum erwiesen ist und die erheblichen Risiken nicht mehr zu leugnen sind, müsste man folgerichtig ein EU-Verbot fordern. Oder zumindest abschreckende Warnaufdrucke, ähnlich der Zigarettenschachteln. Die werden auch nicht weniger schädlich, wenn man das billige Kraut raucht.

PS: Auch Microsoft hatte seine Sicherheitsgaus - bis vor etwa 10 Jahren (SQLSlammer), danach nicht mehr.

Alexander Schmidt: Windows 8.1 Problemchen gelöst und einige nette Highlights

Nachdem ich mein Entwicklungssystem auf Windows 8.1 hochgezogen habe, nervten mich sogleich 2 Dinge. Ich habe jeweils eine Lösung gefunden möchte dies keinem codingfreaks-Leser vorenthalten. Zum Schluss zeige ich interessierten Lesern noch ein paar meiner Win 8.1 Update 1 Highlights. Problem Nummer 1: Windows Version unten rechts Ich habe zwar bereits ein ziemlich neues Motherboard […]

ppedv Team Blog: Das April-Update für Windows 8.1 und Server 2012 R2

Zeitgleich mit dem Ende vom Support für Windows XP (und dem damit verbundenen letzten Patchday für eben dieses) veröffentlichte Microsoft am 8. April 2014 ein erstes größeres Update für Windows 8.1 und Windows Server 2012 R2:

http://support.microsoft.com/kb/2919355

Entgegen den Erwartungen bringt dieses Patch das "alte" Startmenü nicht zurück (dies soll mit einem weiteren Update vermutlich im Herbst nachgeliefert werden), hat aber dennoch einige Verbesserungen an Bord. Diese zielen vor allem darauf ab, die Bedienung mit Tastatur und Maus zu verbessern. Dazu gehören u.a. folgende Veränderungen:

  • Das System unterscheidet bei einigen Aktionen, ob diese mit der Maus oder dem Touchscreen ausgelöst wurden
  • Fährt man mit der Maus in einer geöffneten Modern UI App an den oberen Bildschirmrand, erscheint eine Box zum Minimieren und Schließen, so wie man es aus klassischen Fenster-Anwendungen kennt
  • Am unteren Bildschirmrand wird die Taskleiste eingeblendet
  • Ein Rechtsklick auf eine Kachel liefert diverse häufig genutzte Optionen
  • Verknüpfungen zu Modern UI Apps können auf der Taskleiste abgelegt werden
  • Auf der Startseite gibt es jetzt einen eigenen Button für den Shutdown, zusätzlich einen für die Suche

Neben diesen Änderungen werden eine ganze Reihe bekannter Probleme behoben. Welche genau kann man im TechNet KB Artikel nachlesen:

http://support.microsoft.com/kb/2919355/en-us

Das Update ist knapp 890MB groß und wird u.a. über Windows Update verteilt.

Klaus Aschenbrenner: Improving Query Performance by using correct Search Arguments

(Be sure to checkout the FREE SQLpassion Performance Tuning Training Plan, where you are getting week by week via email all the essential knowledge you need to know about performance tuning on SQL Server.)

In today’s blog posting I want to talk about a very specific performance problem related to indexing in SQL Server.

The Problem

Imagine the following simple query, which you have already seen hundreds of times in your SQL Server life:

-- Results in an Index Scan
SELECT * FROM Sales.SalesOrderHeader
WHERE YEAR(OrderDate) = 2005 AND MONTH(OrderDate) = 7
GO

With that simple query, we request sales information for a specific month in a specific year. Not very complicated. Unfortunately that query doesn’t perform very well – even with a Non-Clustered Index on the column OrderDate. When you look at the execution plan, you can see that the Query Optimizer has chosen the Non-Clustered Index that is defined on the column OrderDate, but unfortunately SQL Server performs a complete Scan of the index, instead of performing an efficient Seek operation.

Non Clustered Index Scan

This isn’t really a limitation of SQL Server, this is the way how relational databases are working and thinking :-) . As soon as you are applying an expression (function calls, calculations) on an indexed column (a so-called Search Argument), the database engine HAS TO SCAN that index, instead of performing a seek operation.

The Solution

To get a scalable seek operation in the execution plan, you have to rewrite your query in a way to avoid the call of the function DATEPART:

-- Results in an Index Seek
SELECT * FROM Sales.SalesOrderHeader
WHERE OrderDate >= '20050701' AND OrderDate < '20050801'
GO

As you can see from the rewritten query, the query returns the same result, but we have just eliminated the function call of DATEPART. When you look at the execution plan, you can see that SQL Server performs a seek operation – in that specific case it is a so-called Partial Range Scan: SQL Server seeks to the first value, and scan until he hits the last value of the requested range. If you have to call functions in the context of indexed columns, you should always make sure that these function calls are performed on the right hand side of your column in the query. Let’s have a look at a concrete example. The following query casts the indexed column CreditCardID to the data type CHAR(4):

-- Results in an Index Scan
SELECT * FROM Sales.SalesOrderHeader
WHERE CAST(CreditCardID AS CHAR(4)) = '1347'
GO

When you have a more detailed look on the execution, you can see that SQL Server scans again the whole Non-Clustered Index. Not really scalable if your table gets larger and larger. If you are performing that conversation on the right hand side of your indexed column in the query, you can again eliminate the function call on the indexed column, and SQL Server is able to perform a seek operation:

-- Results in an Index Seek
SELECT * FROM Sales.SalesOrderHeader
WHERE CreditCardID = CAST('1347' AS INT)
GO

Another nice example where you can run into the same problems is the use of the CASE expression in SQL Server. Let’s have a look at the following query, where the column PersonType is indexed through a Non-Clustered Index:

-- Results in an Index Scan
SELECT
	CASE PersonType
		WHEN 'IN' THEN 1
		WHEN 'EM' THEN 2
		WHEN 'SP' THEN 3
		WHEN 'SC' THEN 4
		WHEN 'VC' THEN 5
		WHEN 'GC' THEN 6
	END AS ConvertedPersonType
FROM Person.Person
GO

You are calling here again a function on an indexed column, in our case the CASE expression. You can’t directly see that function call in the T-SQL query, but internally it’s nothing more than a function call. You are getting again a Scan of the Non-Clustered Index instead of a Seek operation. How can you avoid that problem? You can rewrite the query to get rid of the CASE expression. One example is a join against a Common Table Expression, which stores the needed lookup values. Let’s have a look on the rewritten query:

-- Results in an Index Seek
WITH LookupCTE AS
(
	SELECT * FROM
	(
		VALUES
			(N'IN', 1),
			(N'EM', 2),
			(N'SP', 3),
			(N'SC', 4),
			(N'VC', 5),
			(N'GC', 6)
	) tbl (PersonType, Value)
)
SELECT cte.Value FROM Person.Person p
INNER JOIN LookupCTE cte ON cte.PersonType = p.PersonType
GO

With that approach, SQL Server is able to perform a seek operation on the indexed column PersonType.

Summary

As you have seen in this blog posting, it is very important that you are NOT calling any function directly or indirectly on your indexed columns. Otherwise SQL Server has to scan your index, instead of performing an efficient seek operation. And scans will never ever scale, when your table gets more and more rows.

Please feel free to leave a comment, if you want to share other good examples where you have encountered this specific behavior.

Thanks for reading!

-Klaus

ppedv Team Blog: Data Annotations Webforms und Bootstrap ausgereizt

Auf dem Weg zum Lazy Web Developer habe ich dieses Mal den Data Annotations auf den Zahn gefühlt. In Silverlight war das richtig geiler Scheiss.

Man kann einer Klasse per Property-Attributen Regeln mitgeben. Diese werden Data Annotations genannt. Die Regeln können sich auf Darstellung, Reihenfolge oder Gültigkeit eines Propertys beziehen.

   1:  Public Class daten1
   2:      <Key()>
   3:      Property id As Integer
   4:      <Required(ErrorMessage:="brauche Daten")>
   5:      <EmailAddress(ErrorMessage:="brauche email")>
   6:      Property email As String
   7:      <Required(ErrorMessage:="musse haben")>
   8:      Property name As String
   9:  End Class

In der richtigen Umgebung werden diese Klassenattribute ausgewertet.

ASP.NET nutzt die Klassenattribute über Dynamic Data. Eingebettet in ein Datensteuerelement wertet das DynamicEntity-Steuerelement das gebundene Objekt (Itemtype) aus.

   1:      <link href="../Content/bootstrap.css" rel="stylesheet" />
   2:      <script src="../Scripts/jquery-2.0.3.js"></script>
   3:      <script src="../Scripts/bootstrap.js"></script>
   4:  </head>
   5:  <body>
   6:      <form id="form1" runat="server">
   7:      <div>
   8:          <asp:FormView ID="FormView1" DataKeyNames="id" 
ItemType="daten1"
   9:               runat="server" DefaultMode="Insert">
  10:              <InsertItemTemplate>
  11:                  <asp:DynamicEntity runat="server" ID="eins" 
Mode="Insert"/>
  12:                  <asp:Button runat="server" CommandName="Insert" 
Text="insert" class="btn btn-default"/>
  13:              </InsertItemTemplate>
  14:          </asp:FormView>
  15:      </div>
  16:      </form>
  17:  </body>

 

Die Magie geschieht im Verzeichnis Dynamic Data. Je nach Mode (hier insert), wird das Template aus EntityTemplate geladen.

image

Dieses Template wurde von mir leicht angepasst, um den Bootstrap 3 Formular-Regularien zu folgen.

   1:  <asp:EntityTemplate runat="server" ID="EntityTemplate1">
   2:      <ItemTemplate>
   3:          <div class="form-group">
   4:              <asp:Label ID="Label1" runat="server" OnInit="Label_Init"
   5:                  OnPreRender="Label_PreRender" 
CssClass="col-sm-2 control-label" />
   6:              <div class="controls">
   7:                  <asp:DynamicControl runat="server" ID="DynamicControl"
   8:                      Mode="Edit" OnInit="DynamicControl_Init" />
   9:              </div>
  10:          </div>
  11:      </ItemTemplate>
  12:  </asp:EntityTemplate>

 

Das DynamicControl-Element wird dann passend zum Datentypen durch ein Template aus dem Verzeichnis FieldTemplate ersetzt. In diesem Beispiel Integer_Edit, Text_Edit und EMailAddress_Edit.

Folgendes deklarative ASP.NET Code-Beispiel zeigt das Text-Template. Wichtig ist Display Dynamic einzustellen, um den Platz in der Darstellung nicht zu verbrauchen, wenn keine Fehlermeldung angezeigt wird. Außerdem verwendet Bootstrap für sein error HTML Template die CSS-Klasse help-block. Ergebnis ist roter Text.

   1:  <asp:TextBox ID="TextBox1" runat="server" Text='<%# FieldValueEditString %>'
   2:       CssClass="form-control"></asp:TextBox>
   3:   
   4:  <asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator1" 
CssClass="help-block" ControlToValidate="TextBox1" Display="Dynamic" Enabled="false" />
   5:  <asp:RegularExpressionValidator runat="server" ID="RegularExpressionValidator1" 
CssClass="help-block" ControlToValidate="TextBox1" Display="Dynamic" Enabled="false" />
   6:  <asp:DynamicValidator runat="server" ID="DynamicValidator1" 
CssClass="help-block" ControlToValidate="TextBox1" Display="Dynamic" />
   7:   

Die ASP.NET Validation Controls haben allerdings ein Feature, das hier stört. Diese können mit einem Stern die Fehlerposition  und den beschreibenden Fehlertext in einem ValidationSummary Control anzeigen. Wir wollen aber den Fehlertext direkt unterhalb der Eingabe sehen.

Folgender übler Trick ersetzt per VB.NET Code im Page Load Event des ASCX Files den Stern und damit wird der volle Text gezeigt:

   1:  RegularExpressionValidator1.Text = ""
   2:  RequiredFieldValidator1.Text = ""
   3:  DynamicValidator1.Text = ""

Dann füge ich noch eine JavaScript-Datei hinzu, die CSS-Attribute austauscht für has-errors wenn die Eingabe nicht valid ist. Dies ist in einem anderen Blog-Artikel beschrieben.

   1:  var proxied = window.ValidatorValidate;
   2:   
   3:  window.ValidatorValidate = function () {
   4:   
   5:      var result = proxied.apply(this, arguments);
   6:      onAfter(arguments);
   7:   
   8:  };
   9:   
  10:  var onAfter = function (arguments) {
  11:      var control = document.getElementById(arguments[0].controltovalidate);
  12:      var validators = control.Validators;
  13:      var isValid = true;
  14:   
  15:      for (var i = 0; i < validators.length; i++) {
  16:          if (!validators[i].isvalid) {
  17:              isValid = false;
  18:              break;
  19:          }
  20:      }
  21:   
  22:      if (isValid) {
  23:          $(control).closest('.form-group').removeClass('has-error');
  24:      } else {
  25:          $(control).closest('.form-group').addClass('has-error');
  26:      }
  27:  };

Bei einem Submit des Formulars sieht das im Internet Explorer  so aus:

image

Sehr cool, was die ASP.NET Steuerelemente zusammen mit Bootstrap hier so zaubern. Allerdings sind sie einen Hauch zu intelligent. Es werden nämlich auch korrekt die neuen HTML5 Input-Typen gerendert (Type=”number” und Type=”email”). Moderne Browser validieren dann auch gleich mal selber was im IE bei falscher E-Mail-Adresse so aussieht:

image

Zuerst erscheint ein browserspezifisches Popup und wenn man das Feld per TAB verlässt, wird es rot eingerahmt.

Da wir uns hier in den Händen des Browsers befinden, sieht das dann Chrome auch deutlich anders. Die fehlerhafte Eingabe wird gar nicht mehr hervorgehoben und die Nummer wird von einem Updown Icon begleitet.

image

In den Bootstrap-Foren wurde das Thema auch diskutiert und dann geschlossen. Theoretisch wäre auch das Required-Attribut ein HTML5-Standard, hier erzeugt ASP.NET aber stattdessen ein DIV. Optisch besser aber nicht konsistent. Bei meiner Recherche habe ich ein Plugin gefunden, habe aber ein wenig Probleme für das Framework, das für die Unzulänglichkeiten von CSS erfunden wurde, ein Plugin zu verwenden, das die Unzulänglichkeiten des Frameworks fixed. Im ersten Test gibt es einen Konflikt mit meiner eigenen JS Library. Selbst wenn ich das fixe, kann schon morgen mit dem nächsten Nuget-Update wieder alles hin sein.

Holger Schwichtenberg: Zusammenfassung von Microsofts BUILD-Konferenz 2014

Die BUILD-Konferenz brachte Neuigkeiten zu Windows 8.x, Windows Phone, Windows Azure sowie .NET, C# und Visual Studio.

ppedv Team Blog: Form-Validierung für Bootstrap

Es gibt verdammt viele Möglichkeiten, um Benutzereingaben zu validieren. Im Webumfeld werden es sogar mehr statt weniger. Hinzu kommen Anforderungen an das Design. Client oder Server? Ganz schön viel für einen kleinen Blogartikel, der sich um ASP.NET-Formulare in Verbindung mit Bootstrap 3 kümmert.

Bootstrap ist ein Framework für einfacheres Webdesign. Responsive Design fast ohne CSS anzufassen. Microsoft setzt in Visual Studio 2013 und seinem One ASP.NET Template auf die aktuelle Version Bootstrap 3. Ist also schon drin. Ideal also für eine schnelle Validierung am Client.

Das HTML Template setzt sich aus geschachtelten DIV zusammen und vor allem dem Attribut has-error. In der  Version 2 lautete das noch control-group und error.

   1:   <div class="form-group has-error">
   2:          <label class="control-label" for="text1">Feldbeschreibung
</label>
   3:          <div class="controls">
   4:              <input type="text" class="form-control" id="text1">
   5:              <span class="help-block">Fehlermeldung</span>
   6:          </div>
   7:  </div>

und sieht dann so aus. Der Fehler ist sozusagen hart verdrahtet.

image

Nun stellt sich sowohl für den ASP.NET MVC und auch den Webforms Frontend Designer die Frage, wie man die Validation Controls bzw. HTML Validation Helper dazu bewegt da mitzuspielen. Das Problem liegt vor allem darin, dass die Fehlermeldung einen übergeordneten Node im HTML Dom verändern muss. Aus Programmierersicht ist es ohnehin verpönt, Elemente (oder Objekte) in Abhängigkeit zu stellen.

Die Alternative, komplett neue Steuerelemente zu entwickeln, erscheint wenig verlockend.

Betrachten wir die Eingabevalidierung mit ASP.NET Web Forms unter Anwendung der vorigen Bootstrap HTML Vorlage. Es soll geprüft werden, ob die Eingabe eine gültige E-Mail-Adresse ist. Visual Studio schlägt in den Control-Eigenschaften die passende Regular Expression vor.

   1:  <div class="form-group" id="test1">
   2:          <asp:Label ID="Label2" runat="server" Text="Beschriftung"
   3:           CssClass="col-sm-2 control-label" />
   4:          <div class="controls">
   5:              <asp:TextBox ID="TextBox1" runat="server" 
CssClass="form-control">
   6:  </asp:TextBox>
   7:              <asp:RegularExpressionValidator 
ID="RegularExpressionValidator1" runat="server"
   8:                  SetFocusOnError="true"
   9:                  ErrorMessage="RegularExpressionValidator" 
ControlToValidate="TextBox1"
  10:  ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">
  11:  </asp:RegularExpressionValidator>
  12:          </div>
  13: </div>    

Als nächstes kommt JavaScript und JQuery Magic zum Einsatz. Mein großes Problem war herauszufinden, wo man während der Validierung einhaken kann. Das Validator Control blendet dynamisch ohne Postback die Fehlermeldung ein bzw. aus - dank moderner unobtrusive Validation von ASP.NET Webforms auch mit JQuery Validierung. Im HTML Code wird ein SPAN Element erzeugt. Data-Attribute werden für die Validierung verwendet.

   1:   <input name="ctl00$Inhalt$TextBox1" type="text" 
id="Inhalt_TextBox1"
   2:  class="form-control" />
   3:   
   4:  <span data-val-controltovalidate="Inhalt_TextBox1" 
data-val-focusOnError="t"
   5:  data-val-errormessage="RegularExpressionValidator" 
   6:  id="Inhalt_RegularExpressionValidator1" data-val="true" 
   7:  data-val-evaluationfunction="RegularExpressionValidator
EvaluateIsValid"
   8:  data-val-validationexpression="\w+([-+.&#39;]\w+)*@\w+
([-.]\w+)*\.\w+([-.]\w+)*"
style="visibility:hidden;">
RegularExpressionValidator</span>
   9:          </div>

Bleibt die Frage, wie man aus dem SPAN da, oder nicht da, auf ein übergeordnetes DIV kommt. Ginge, aber ich habe ein Event gefunden, das schon seit Ewigkeiten in der Library existiert, ValidatorValidate.

Diese Methode wird dann überschrieben, wie man das aus OOP so kennt, um seine eigene Logik (onAfter) hinten dran einzufügen. Dann wird die CSS Klasse has-error zugewiesen, wenn ein Fehler auftritt.

   1:  <script>
   2:   var proxied = window.ValidatorValidate;
   3:         window.ValidatorValidate = function () {
   4:          var result = proxied.apply(this, arguments);
   5:          onAfter(arguments);
   6:         };
   8:         var control = document.getElementById(arguments[0].
controltovalidate);
   9:         var validators = control.Validators;
   7:         var onAfter = function (arguments) {
  10:         var isValid = true;
  11:         for (var i = 0; i < validators.length; i++) {
  12:                  if (!validators[i].isvalid) {
  13:                      isValid = false;
  14:                      break;
  15:                  }
  16:              }
  17:             if (isValid) {
  18:                  $(control).closest('.form-group').
removeClass('has-error');
  19:              } else {
  20:                  $(control).closest('.form-group').
addClass('has-error');
  21:              }
  22:          };
  23:  </script>

 

Um ehrlich zu sein, bin ich mir nicht sicher, was ich mir im Detail damit einhandle. Falls es unter den Lesern welche gibt die dazu Feedback haben, per mail an hannesp at ppedv.de oder Facebook.com/preishuber.

Jedenfalls ist der Aufwand nun überschaubar. Einfach als JS-Datei ausgelagert und am besten in der Masterpage included.

ppedv Team Blog: Build-Ankündigungen für Microsoft Azure

Auf der Build-Konferenz, die in dieser Woche in San Francisco stattfand, gab es einige neue Meldungen, natürlich auch zum Thema Microsoft Azure, wie sich die Cloud-Lösung seit dieser Woche nennt.

  • Neues Portal

Seit Donnerstag Abend steht unter https://portal.azure.com/ das neue Portal für Microsoft Azure als Preview zur Verfügung. Dieses neue Portal verknüpft dabei Microsoft Azure und Visual Studio Online. Es soll im Laufe der Zeit um weitere Tools von Microsoft und deren Partnern erweitert werden und auch auf die Wünsche der Kunden angepasst werden.

  • Neue Basiskategorie für Web Sites

Die neue Einsteigerkategorie für Web Sites (Basic) bietet Unterstützung für small, medium und large Virtual Machines. Gegenüber der Standardedition liegen die Preise um 33 % niedriger. Die folgende Grafik zeigt einen Vergleich der verschiedenen Angebote:

Wie Sie aus der Grafik auch erkennen können, wurden die Standardinstanzen auch verbessert. So können Kunden ohne weitere Kosten fünf SNI (Server Name Indication) und ein IP SSL Zertifikat hochladen und nutzen. Automatische Skalierung auf bis zu 10 virtuellen Instanzen und tägliche Backups runden das Angebot ab.

  • Basic Tier auch für Compute Instanzen

Auch im Bereich Cloud-Dienste wird neben der Standardversion eine Basicversion angekündigt, die um 26,67% günstiger sein wird, jedoch kein Loadbalancing und automatische Skalierung unterstützt. Diese Instanzen sind vor allem als Testserver und während der Entwicklung geeignet.

  • Azure Active Directory Premium

Azure Active Directory Premium ist ab sofort generell verfügbar. Alle Kunden, die diesen Service in der Preview genutzt haben, können sich bis zum 1. Juli 2014 entscheiden, ob sie den Dienst bezahlen wollen oder danach das normale Azure Active Directory kostenlos nutzen wollen. Die Premiumversion unterstützt Synchronisation mit dem lokalen Active Directory, Single Sign On und Multifactor Authentifizierung.

  • Scheduler-Dienst verfügbar

Auch ein Scheduler-Dienst ist ab sofort verfügbar. Mit dem Scheduler können Sie Jobs in der Cloud erstellen, die zuverlässig Dienste inner- und ausserhalb der Cloud aufrufen können.

  • Autoskalierung

Applikationen können jetzt so konfiguriert werden, dass sie automatisch auf Basis der aktuellen Nutzung hoch oder auch runterskalieren. Autoskalierung ist möglich für Virtuelle Maschinen, Cloud-Dienste, Web Sites und Mobile Services.

  • weitere verfügbare Dienste

Des Weiteren wurden folgende Dienste generell verfügbar gestellt:

- Visual Studio Online

- Virtual Network Dynamic Routing Gateway und Point-to-Site VPN

- Azure Automation

- Azure Backup 

ppedv Team Blog: Evolution statt Revolution

Nachdem der Staub sich rund um die alljährlichen Ankündigungsreigen der Redmonder Software-Schmiede zu legen beginnt, ist es Zeit ein erstes Fazit zu ziehen. Was bringt uns die Zukunft bzw. was stellt sich Microsoft darunter vor?

Wenn man es ganz nüchtern betrachtet, bleibt eigentlich nur ein Windows Update für 8.1, ein Phone Update von 8 auf 8.1 und eine Reihe von Detail-Änderungen übrig. Daneben noch die faktisch folgenlose Veröffentlichung des Quellcodes einiger neuer Bibliotheken, heute Open Source genannt.

Wer eine Dekade zurückblickt, wird sich erinnern, dass die TechEd Developer sich mit aktuellen und ganz nahen Technologien beschäftigte und die PDC, die Vorgängerin der BUILD, mit den über die nächsten ca. 18 Monaten kommenden. Die BUILD 2014 präsentierte am 2.April ein kleines Windows Update, das am 8.April öffentlich verfügbar sein wird. So ist die Welt heute. Gerade mal eine Woche Zukunft. Roadmaps konnte man in den Slides keine entdecken.

Vor rund fünf Jahren war Windows Mobile 6.5 angesagt. Mit einem kolportierten Marktanteil von ca. 19%. Allerdings war Apple unaufhaltsam auf dem Vormarsch und so entschlossen sich die Redmonder zu einem radikalen Schnitt: es den Jungs aus Cupertino gleich zu tun.

Ich erinnere mich noch gut an ein frühes Meeting bei Microsoft. Ein Kreis erlauchter externer Experten, eine Handvoll Microsofties und meine Wenigkeit. Das Produkt, das da vorgestellt wurde, hatte alle Nachteile von Apple gewonnen und die Vorteile von Microsoft verloren. Ich werde heute noch auf meine unbarmherzige Kritik angesprochen. Und ich habe mit jedem Strich und Punkt Recht behalten. Meine damaligen Vorschläge werden jetzt umgesetzt. Der Marktanteil dümpelt heute noch unterhalb des damaligen Windows Mobile rum. Dennoch hatte auch Microsoft Recht. Es musste ein harter Kurswechsel her. Windows Mobile hatte kein Marktpotential für die Zukunft.

Rund zweieinhalb Jahre später, auf der ersten BUILD, wurde dann Windows 8 angekündigt. Ich war persönlich in Anaheim dabei und habe mich von der Begeisterung anstecken lassen. In einem persönlichen Dialog mit einem Produktmanager wurde die Problematik des Rollouts angesprochen. Er war überzeugt, dass der Appstore-Zwang von den Kunden angenommen wird. Ich nicht. Ein anderer wichtiger Produktmanager war überzeugt, dass bald ohnehin nur mehr touchfähige Devices ausgeliefert werden. Ein folgenschwerer Irrtum, wie sich aus heutiger Sicht zeigt. Der wesentlichste Fehler ist uns und damit meine ich Microsoft und mich, in der  Einschätzung der Verbreitung von Windows 8 und Devices unterlaufen. Meine persönliche Prognose war: 100 Millionen Touch Devices bis 31.Dezember des Erscheinungsjahrs, sonst wird Balmer seinen Hut nehmen müssen. Es waren bei weitem nicht so viele und Balmer ist Geschichte.

Ganz wesentlich ist aber die falsche Consumer-Strategie. Consumerization von IT ist zwar Tatsache, wie auch bei HTML5, aber deren Folgen sind völlig falsch eingeschätzt worden. Die Unternehmen haben keine APPS erstellt. Punkt.

Windows 8 hatte nie ein Qualitätsproblem. Es war schön, modern, einfach zu bedienen. Auf Tablets für den Neueinsteiger völlig intuitiv. Eine Sensation ohne Startbutton. Es sind die über 1 Milliarde Microsoft-Benutzer, die nicht mitspielen. Folgerichtig kann man in den Blogs und Tweets im Tenor lesen, was es eh jeder schon die ganze Zeit sagt: Hört den Kunden zu. Steve Jobs und Steven Sinofsky waren anderer Meinung: Innovation kommt nicht aus Marktforschung.

Ganz anders die Keynotes der BUILD 2014. Wir haben zugehört, hier habt Ihr das Resultat. Auch ein Startmenü gibt es dazu. Und wir nehmen euch euer geliebtes .NET und XAML nicht weg. JavaScript erwähnen wir gar nicht, weil ihr es hasst.

Die Teilnehmer sind begeistert. Twitter quillt über von positiven Feeds: Beste BUILD ever. Vor allem die gemeinsame Codebasis für Phone und Windows wird gelobt. Auch die vereinfachte Sideloading Policy, die faktisch den Store aushebelt, stößt auf Begeisterung.

Die Realität bildet das aber nur zum Teil ab. Weite Teile des Developer Eco Systems beschäftigen sich heute mit HTML5 als Frontend-Technologie. Ich halte diese zwar für grottig, aber vorhanden. Da das Problem mit dem Standard und Browsern systemimmanent ist, erwarte ich keine relevante Besserung. In Angesicht dessen bin ich immer wieder erstaunt, welche großartigen Ergebnisse trotz widriger Umstände erzielt werden.

Diese Community wird auch mit dem Honig Open Source und Nuget kaum kleben bleiben. Das sind die Leute, die nicht auf die BUILD gehen.

Aus dem Applaus und den Besucherzahlen der aufgezeichneten Sessions lassen sich ein paar Trends erkennen. C# und .NET sind weiter top angesagt. Multiplattform-Entwicklung auf dem .NET-Technologiestack wird eindeutig gewünscht und von XAMARIN bedient. Azure ist trotz Scott Guthrie bei weitem nicht das führende Thema.

Schon im Vorfeld hat Microsoft eine Art Office für die Apple-Plattform gelauncht. Ein Eingeständnis der schwindenden Bedeutung von Windows. Dies wird auch mit einem Startmenü nicht besser werden. Die Fokussierung auf das angestammte Publikum, die Vereinheitlichung der Plattform Xbox, Windows und mobile werden helfen, nicht noch weitere Kunden zu vergraulen.

Die nächste Welle wird allerdings woanders an den IT-Strand laufen: das Internet of Things, oft ohne UI, aber damit mit hohem Bedarf an Service-Kommunikation. Davon sah man im BUILD-Programm recht wenig.

Hannes Preishuber besucht seit rund 15 Jahren Microsoft-Konferenzen. Er war Teilnehmer der legendären Hailstorm PDC, deren Visionen und Produkte nie Realität wurden. Auch Projekt Oslo und die Programmiersprache M kennt heute keiner mehr. Obwohl Clippy das selbe Schicksal erleiden musste, war er kein PDC Announcement. 2003 diskutierte er auf der PDC in Los Angeles mit dem noch unbekannten Miguel de Icaza über .net und dessen von Microsoft ungewünschte Implementierung als Mono. Die BUILD Konferenz 2014 besuchte er nur virtuell. Trotz entsprechender Gerüchte nicht wegen des Essens.

Karsten Kempe: ALM-Forum 2014 – Tag 3

header (2)All good things come to an end. So ging auch gestern die dreitägige Konferenz ALM-Forum in Seattle zu Ende. Drei Tage vollgepackt mit informativen Vorträgen, interessanten Gesprächen und ganz viel Kaffee. Steven Borg hat mir Stein und Bein geschworen, dass es in Seattle den besten Kaffee gibt. Für mich gab es gestern auch wieder zwei Vorträge, die sich von den anderen abgehoben haben. Zum einen Roy Osherove, der in seinem Vortrag „Notes to a Team Leader“ sehr mitreißend erklärt hat, wie man an Herausforderungen wachsen kann und zum anderen Dave West, der mit seinem Wissen über „Lean ALM“ beeindruckt hat.

Den Startschuss zum letzten Konferenztag gab Sam Guckenheimer mit dem mir schon bekannten Vortrag „Transforming software development in world of services“. Sam berichtete von den Erfahrungen, die Microsoft auf dem Weg zu einem sehr agilen Vorgehen gemacht hat.

alm-forum2_01_cloudcadence

In meinem Post zu den ALM-Days im Februar hatte ich den Inhalt von Sams Vortrag noch detaillierter zusammengefasst und er kann dort gerne nachgelesen werden.

Der zweiten Talk, den ich besuchte, war die Fortsetzung der Keynote von Mike Brittain vom zweiten Konferenztag. In „Advanced Topics in Continuous Deployment“ beschrieb Brittain, wie der Deployment-Prozess der e-Commerce Plattform Etsy Schritt für Schritt verbessert wurde. Etsy erreicht die unglaubliche Anzahl von bis zu 30 Deployments pro Tag durch ein sehr ausgereiftes System, welches im Wesentlichen aus vier Elementen besteht: Config flags, Automatisierten Deployment-Prozessen, Semi-automatisierten Release Management und Vorwärtsorienierte Schema Änderungen.

Erst der Einsatz von config flags, macht ein ständiges Bereitstellen neuer Code-Änderungen in die Produktionsumgebung möglich. Denn so können Code-Stellen über die Konfiguration „an- und abgeschalten“ werden und Änderungen vorerst vor den Benutzern verborgen werden.

Erst wenn die Bereitstellung komplett automatisiert ist, kann sie schnell und flüssig erfolgen. So stellt Etsy für die Produktionsumgebung immer einen live Cluster und einen „dark“ Cluster bereit. Deployments werden demnach immer zuerst auf den dark Cluster ausgerollt, vertestet und erst wenn alles in Ordnung ist, wird der Cluster-Traffic durch ein config flag umgeschaltet.

Unter semi-automatisierten Release Management versteht Mike Brittain einen benutzergesteuerten Release-Prozess, d.h. jeder Entwickler, der eine Änderung ausrollen will, muss sich mit anderen Entwicklern (max. bis zu sieben Entwicklern) zusammenschließen und den Deployment-Prozess koordinieren. Laut Brittain ist eine Automatisierung hier nicht erwünscht, da sehr oft individuelle Entscheidungen getroffen werden müssen, die vom Standard abweichen.

Schema-Änderungen werden bei Etsy wie Interface-Änderungen behandelt. Dabei wird immer wie folgt vorgegangen:

alm-forum2_04_etsy

Tipps, wie Continuous Deploymemt erreicht werden kann, gab Mike Brittain seinen Zuhörern auch noch mit auf dem Weg. Es sei am besten klein anzufangen (mit wenigen Flags), Test-Automatisierung und Monitoring der Produktionsumgebung einzuführen und  für den Notfall eine Fallback-Strategie zu entwickeln, falls doch einmal ein Deployment schiefgelaufen ist.

Eine sehr mitreißende Vorstellung bot Roy Osherove. Osherove ist Autor des Buches „Notes to a software team leader“ und Blogger auf 5whys.com. In seinem Vortrag befasste er sich mit der Frage, welche Aufgaben ein Team-Leiter haben sollte. Und in seinen Augen ist die Hauptaufgabe eine Leaders, seine Mitarbeiter besser zu machen. Er sollte sie motivieren nach Herausforderungen zu suchen, von denen sie bis dato noch nicht einmal wussten, dass sie diese Herausforderung überhaupt suchen könnten. Denn nur wenn der Mensch aus seiner Komfort-Zone herausgelockt wird, entfaltet er sein größtes Potential um sich zu verbessern.

alm-forum2_05_leaders

Osherove selbst lebt auch nach diesem Motto und sucht sich ständig selbst immer neue Herausforderungen, an denen er wachsen kann. Ein echt starker Typ und Entertainer.

Abschließend möchte ich noch etwas über die Closing-Keynote von Dave West, dem Chief Product Officer von Tasktop, berichten. In „Lean ALM: Making Software flow from idea to implementation“ arbeitete West vier wichtige Faktoren heraus, die für ihn über Erfolg und Misserfolg im Umgang mit immer komplexer werdender Software entscheiden und mit Lean Software Development zusammen hängen.

Autonomy – Adaptability – Transparency – Collaboration

Wie in Dan Pinks „Puzzle of Motivation” sehr gut beschrieben ist, führt Autonomie zu mehr Leistung und Motivation. In einer Welt von Knowledge Workern ist Autonomie sehr wichtig und erstrebenswert. Aber wie passt Autonomie in einen ALM-Prozess, in dem Werte vorgegeben und gemessen werden? Nun, das verlangt den Führungskräften einiges an Fingerspitzengefühl ab, um da die richtige Mischung zu finden.

Agil sein bedeutet auch, sich immer an die bestehenden Gegebenheiten anzupassen. West zeigte auf, dass Agil-sein in der heutigen Software-Entwicklung eher ein hybrides Modell bedeutet, in dem Requirements-Engineering, Planung und ein zyklisches Vorgehen eine große Rolle spielen. Er nannte dieses Modell „Water-Scrum-Fall“!

alm-forum2_17_lean

Und die Schwierigkeit von „Water-Scrum-Fall“ ist, dass es unterschiedliche Zyklen zwischen den einzelnen Artefakten gibt, die am Ende irgendwie zusammengeführt werden müssten – einmal von langer Hand geplante Requirements und andererseits sehr schnell umgesetzte “Entwickler-Tasks”.

Transparenz ist wichtig im agilen Vorgehen und in ALM schon fast unumgänglich. Nur wenn alle Prozess-Teilnehmer zu jeder Zeit alle Informationen haben, können komplexe Systeme gebaut und beherrschbar gemacht werden.

Und der letzte wichtige Faktor, um die zunehmende Komplexität der Systeme zu meistern, ist Zusammenarbeit. Software-Entwicklung ist Teamarbeit. Nur gut eingespielte und gut zusammenarbeitende Teams vollbringen Höchstleistung.

alm-forum2_18_lean

Unternehmen, die es schaffen, all diese Punkte zu erfüllen, haben laut West die größten Chancen, mit den Herausforderungen der heutigen Software-Entwicklung, im Zeitalter des „Internet of things“, schrittzuhalten.

  1. Highlights des dritten Tages

Holger Schwichtenberg: Zusammenfassung der zweiten Keynote der BUILD 2014

Die zweite Keynote der BUILD-2014-Konferenz bot im Wesentlichen Neuigkeiten zu Microsoft Azure und ein wenig auch zu .NET und Visual Studio.

Alexander Schmidt: Cooler wär’ besser!

Es ist mal wieder //build-Zeit. Für einen wie mich heißt das, den normalen Arbeitsprozess zu unterbrechen und mich der Wonne der endlosen Screencasts hinzugeben. Gestern gings los und ich habe es endlich mal geschafft, live bei der Keynote dabei zu sein. Die Eindrücke nach dieser und einigen weiteren Sessions möchte ich schon mal zum besten […]

Kazim Bahar: Session Videos der build 2014 Konferenz

Auf der diesjährigen //build/ Konferenz sind eine Menge Neuerungen rund um das Thema Windows 8 der Entwicklergemeinde vorgestellt worden. Microsoft...

Karsten Kempe: ALM-Forum 2014 – Tag 2

header (2)Gestern ging es im ALM-Forum in Seattle ähnlich spektakulär weiter wie gestern. Die Highlights waren auf jeden Fall die Eröffnungs-Keynote des Scrum-Vaters Ken Schwaber und die Abschluss-Keynote von Steve Denning. Die beiden Speaker wussten mit Fragen ”Wie ist der Erfolg von agilen Techniken messbar” und “Wie kann traditionelles Management von Agile überzeugt werden” das Publikum zu unterhalten.

Die erste Keynote des Tags wurde von Ken Schwaber, dem (Mit-)Erfinder von Scrum, gehalten. Schwaber versuchte in seiner Keynote „The State of Agile“ der Frage nachzugehen, wie der Erfolg von agilen Methoden und Praktiken gemessen werden kann.alm-forum2_ken

Dass agile Frameworks wie Scrum oder Kanban positiven Einfluss auf Unternehmensprozesse haben, ist  mittlerweile in der Software-Branche bekannt. In einer Umfrage im Jahr 2013 konnte Foerster Research sogar feststellen, dass agile Unternehmen erfolgreicher komplexe Software entwickeln können und mehr Geld verdienen als jene, die nach herkömmlichen nicht-agilen Prinzipien arbeiten.

alm-forum2_forrester

Aber die große Frage, der Ken Schwaber nun nach mehr als zehn Jahren Scrum nachzugehen versucht, ist, wie kann der Erfolg von agilen Praktiken belegt werden, ohne sich nur auf Vermutungen zu verlassen? Was ist der unmittelbare Beweist dafür, wie agil sein wirkt?

alm-forum2_nostate

Schwaber untersucht derzeit mit einen Ansatz, der sich “Evidence-Based Management” nennt, den Erfolg von Scrum messbar zu machen. Er versucht damit herauszufinden, welchen tatsächlichen Einfluss agile Prinzipien auf die Softwareentwicklung ausüben.

Evidence-Based Management
Evidenzbasiertes Management ist am ehesten mit Beweisgestützte Unternehmensführung übersetzbar und tritt grundsätzlich dafür ein, Management-Praktiken in sozial- und verhaltenswissenschaftlichen Befunden zu verankern und formale Rückblicke und Evaluationen auf Handlungen oder Ereignisse als zwingende Grundlage für weiteres Handeln anzusehen. Quelle: wikipedia 

alm-forum2_evidence

Wollen wir hoffen, dass er uns bald Beweise vorlegen kann. Vielleicht schon beim nächsten ALM-Forum.

Ein beeindruckenden Vortrag über „Principles and Practices of Continuous Deployment” hielt Mike Brittain, Director of Engineering bei Etsy. Etsy ist eine e-Commerce Plattform für den An- und Verkauf von handgemachten Produkten. Bei Etsy wird jede Änderung, die in einem erfolgreichen Build endet, in das Produktivsystem ausgeliefert. Was dann auch mal zur Folge haben kann, dass pro Tag mehr als 30 Deployments durchgeführt werden.alm-forum2_deploy

Etsy erreicht das durch eine sehr durchdachte Release-Pipeline und die Verwendung von Configuration Flags. So wird z.B. nur in einer perfekten Kopie der Produktivumgebung jede Änderung getestet und Configuration Flags ermöglichen das Freischalten oder Abschalten von Features in der Produktivumgebung.

Die Art und Weise wie bei Etsy Software entwickelt und ausgeliefert wird, ist voll und ganz auf den Deployment-Prozess zugeschnitten. Denn das Einzige was für Etsy zählt, ist die Lauffähigkeit ihrer Webseite und die Reaktionszeit, um Bug-Fixes in das Produktivsystem einzuspielen.

Bevor der Tag durch eine hervorragende Abschluss-Keynote von Steve Denning beendet wurde, konnte ich eine weitere Bird-of-a-feather Session (HOF) zum Thema „Fundamentals of Lean Software Delivery“ besuchen. Und ich muss sagen, diese persönliche und interaktive Art ein Thema zu besprechen, finde ich wirklich genial. Zuerst stellten sich alle Teilnehmer vor und teilten ihre Erwartungen an die BOF-Session mit. Diese Erwartungen und die aufkommenden Fragen wurden dann auf ein Whiteboard geschrieben und von der Gruppe gemeinsam diskutiert.

alm-forum2_bof

Birds-of-a-feather Session sind wirklich eine super Möglichkeit, um von den Erfahrungen von vielen und nicht nur von der Meinung eines einzelnen Sprechers profitieren zu können.

Abgerundet wurde der Tag durch den Vortrag „Transforming managment through agile“ von Steve Denning. Steve Denning hat viele Jahre für die World Bank gearbeitet, ist ausgezeichneter Buchautor und war im Jahre 2000 einer der zehn meist bewundertsten Knowledge Leaders weltweit. Ich muss wirklich sagen, der Mann hat mich beeindruckt. In seiner Session zeigte er die Auswirkungen des traditionellen Managements für eine Firma und seine Mitarbeiter auf und wie diese Denkweise langfristig in den Untergang des Unternehmens endet, weil es mit innovativeren Firmen nicht mehr Schritt halten kann.alm-forum2_value

Seiner Meinung nach, muss sich jedes Management von der traditionellen Zielvorgabe „shareholder value“ zu generieren verabschieden und sich dahingehend entwickeln, die größtmögliche Zufriedenheit seiner Kunden zu erreichen. Und um das zu erreichen, muss ein enormes Umdenken in der Management-Etage der Unternehmen stattfinden.

alm-forum2_value2

Leider hat er meiner Meinung nach viel zu wenig darüber erzählt, wie dieses Umdenken erreicht werden kann. Er gab uns lediglich diese fünf Tipps mit auf den Weg:alm-forum2_value3

Dennoch fand ich die Art und Weise wie Steve Denning vorgetragen hat wirklich herausragend und beeindruckend. Und wenn ich eins von der Session mitgenommen habe, dann war es der Ratschlag „Wenn Du einen Manager überzeugen möchtest, dann musst Du reden wie ein Manager!“

  1. Highlights des zweiten Tages

[0] Wikipedia: Evidenzbasiertes Management

Holger Schwichtenberg: Zusammenfassung der ersten Keynote der BUILD 2014

Die erste Keynote der BUILD-2014-Konferenz bot Neuigkeiten zu Windows, Windows Phone und zur Entwicklung von Cross-Plattform-Apps.

Kazim Bahar: News für Microsoft Entwickler

Bereits am ersten Tag der aktuellen //build/ 2014 Konferenz von Microsoft wurden einige wirklich interessante Neuigkeiten für Entwickler angekündigt. Eines...

Martin Richter: Visual Studio 2013 Update 2 RC ist nun verfügbar

Mit dem neuen SQL 2014 der gestern veröffentlicht wurde kamen auch ein RC für Visual Studio 2013 Update 2. Dabei ist das Update 1 erst ende Januar heraus gekommen.
Das Update 2 für den TFS 2013 ist bereits veröffentlicht worden.
Siehe:  http://blogs.msdn.com/b/bharry/archive/2014/04/02/tfs-2013-2-update-2-released.aspx

Besonders gespannt bin ich auf die Linker Enchantements, die mit Update 2 kommen.
http://blogs.msdn.com/b/vcblog/archive/2014/03/25/linker-enhancements-in-visual-studio-2013-update-2-ctp2.aspx

Die Geschwindigkeit mit der aktuell Updates und Releases veröffentlicht werden ist geradezu verstörend. Man kommt kaum dazu sich auf eine Entwicklungsumgebung festzulegen und da ist schon das nächste Update, dass mit neuen Features Funktionen und Fixes reizt. :(

PS: Die Veröffentlichung von MS-SQL 2014 erinnert mich schmerzhaft, dass es nur noch 5 Jahre Support für OLE-DB gibt. Das ist noch einen traurigen Smiley wert :(


Copyright © 2010 Martin Richter
Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.
(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)

Karsten Kempe: ALM-Forum 2014 – Tag 1

header (2)Gestern hatte ich gleich doppelte Premiere. Zum einen wurde ich zum ersten Mal als Visual Studio ALM MVP ausgezeichnet, und zum anderen nahm ich zum ersten Mal am ALM-Forum teil. Das ALM-Forum findet diesmal im Washington State Convention Center in Seattle statt und bietet allen Teilnehmern eine Plattform, sich über die aktuellen Herausforderungen moderner Software-Entwicklung auszutauschen. Ich werde versuchen, meine Eindrücke dieser Konferenz in einer Blog-Serie niederzuschreiben und meine persönlichen Highlights mit Euch zu teilen.

Meine Highlights von heute waren die Keynote von James Whittaker „A Future Worth Wanting” und die Birds-of-a-feather Session von Steven Borg “What’s git got to do with it”. Aber alles der Reihe nach …

Die Eröffnungskeynote „Disciplined Agile Delivery: The foundation for scaling agile“ wurde von Scott Ambler, dem Co-Creater des DaD Frameworks, gehalten. Scott stellte in der Note Auszüge aus dem DaD Framework vor. DaD steht für Disciplined Agile Delivery und ist laut Scott eine mögliche Antwort auf die Frage, wie große Organisationen agil Software entwickeln könnten. Im Wesentlichen stellt das Framework ein agiles Mindset zur Verfügung, das sich aus sämtlichen agilen Modellen die besten Vorgehens- und Denkweisen herauspickt. Die Grundprinzipien von DaD sind dabei folgende:

DaD

Da das DaD Framework einfach zu mächtig ist um es in eine Keynote zu packen, gab‘s am Abend für jeden Teilnehmer noch eine signierte Ausgabe seines Buches „Disciplined Agile Delivery“.

Als Eröffnungskeynote fand ich das Thema und den Vortrag leider nicht mitreißend genug, da hat mir der Vortrag von James Whittaker wesentlich besser gefallen.

James Whittaker war Redner der zweiten Keynote und befasste sich mit der philosophischen Frage „A future worth wanting“. Auf sehr unterhaltsame Art und Weise entführte James die Zuhörer in eine Zukunft, in der Apps und Devices nicht nur Übermittler von x-beliebigen Informationen sind, sondern Übermittler von genau den Informationen, die mich als Individuum interessieren. Apps sollen noch viel mehr dazu dienen Informationen zu bündeln und benutzerspezifisch aufzubereiten. Die Daten existieren ja längst dazu, denke man nur an die Tonne von Daten, die Facebook oder Google von einem speichert.

whittaker

Ich kann nur jedem empfehlen, wer einmal die Chance hat James Whittaker reden zu hören, sollte sie ergreifen. Der Mann ist einfach „awesome“.

Eine weitere wirklich großartige Session hielt Steven Borg, co-founder von Northwest Cadence und Visual Studio ALM MVP, über das Thema „Metrics that matter: Improving lean and agile, kanban and scrum“. Der wohl prägendste Satz des Vortrags fiel ganz zum Schluss: Metrics are like fire! Powerful but very dangerous!

Und dieser Satz scheint mir sehr richtig und wichtig zu sein, denn jede eingesetzte Metrik hat Konsequenzen – positive also auch negative. Als Beispiel nannte Steven z.B. ein Call-Center, das seine Mitarbeiter an der Anzahl der durchgeführten Telefongespräche pro Tag messen wollte. Die Folge davon war, dass Kundengespräche angenommen wurden, aber schon nach kurzer Zeit einfach der Hörer aufgelegt wurde. So wurden zwar die Anzahl der entgegengenommen Gespräche vervielfacht, aber die Qualität eines einzelnen Anrufs sehr stark reduziert.

Metriken sollten vier Eigenschaften aufweisen: Sie sollten Einfach, Ehrlich, Vergleichbar und Umsetzbar sein.

metrics

Die Hauptmetriken von Scrum (Velocity und Burndown) und Kanban (WIP und Lead Time) kennen wir wohl alle. Das Bemerkenswerte an dieser Tatsache ist allerdings, dass die Modelle Scrum und Kanban meist nur mit diesen wenigen Metriken auskommen, da sich diese Modelle einer anderen, mächtigeren Metrik bedienen – und zwar dem Feedback! Es ist in der agilen Welt viel wichtiger, regelmäßig und zeitnah Feedback über das Entwickelte einzuholen, um zu wissen, ob es das ist, was der Kunde erwartet, als zu messen, wie genau ich in-time und in-budget bin. Denn was nützt es mir, wenn ich meine Software halbwegs in-time und in-budget erzeugt habe, es aber dummerweise nicht ansatzweise das ist, was sich mein Kunde vorgestellt hat.

Steven verriet uns dann auch noch die „metric to rule them all“. Und zwar soll der Schlüssel zum agilen Erfolg die Reduzierung der „Time to feedback“ sein. Also je eher das Feedback kommt, desto schneller kann man eingreifen und desto höher ist mein Erfolg. Probiert’s mal aus!

Als letztes möchte ich noch über eine etwas andere Form der Wissensvermittlung schreiben, die ich so vorher auch noch nicht kannte. Die Session-Variante nennt sich „Birds of a feather“ (BOF) und heißt so viel wie “Zusammenkunft von Gleichgesinnten“. Die BOF-Session, die ich besuchte, wurde ebenfalls von Steven Borg einberufen und hieß „What’s Git got to do with it?“. Ich weiß nicht, ob BOF-Sessions immer so ablaufen, aber ich fand es richtig cool. Als Steven merkte, dass es viele Git-Interessierte gab, die allerdings wenig Erfahrung mit Git hatten, aber wissen wollten, wie Git funktioniert und warum um Git so ein Hype gemacht wird, organisierte er kurzerhand mit ein paar Anwesenden Git-Experten einen kurzen Git-Workshop und zeigte uns ein paar Highlights aus Git. Das nenne ich mal interaktiv …

almforum-bof

Alles in allem fand ich den ersten Tag der Konferenz richtig spannend und unterhaltsam. Mal sehen was der morgige Tag so alles bringt. Stay tuned!

Mehr Infos zum ALM-Forum findet ihr unter www.alm-forum.com

  1. Highlights des ersten Tages

Alexander Schmidt: ABitADay Kickoff

Was macht man, wenn man sein Büro endlich eingerichtet hat, ganz in der Nähe zur Uni ist und glaubt, was im Schädel zu haben, das man anderen gern mitteilen würde? Wir beantworten diese Frage mit “ABitADay”. Über unseren Kickoff hier nun die Bilder und ein paar Erläuterungen. Am 27. März 2014 war es endlich vollbracht. […]

ppedv Team Blog: Weitere Preissenkungen bei Microsoft Azure

Zum 1. Mai wird Microsoft die Preise für Block-BLOB-Speicher deutlich senken. Für lokal redundanten Speicher wird der Preisnachlass 65 Prozent sein, während der Preisnachlass für geographisch redundanten Speicher 44 Prozent beträgt.

Auch die Preise für Virtuelle Maschinen der Kategorie A5 und A7 werden zu diesem Zeitpunkt gesenkt. Linux Virtuelle Maschinen werden zu diesem Zeitpunkt um 35 Prozent billiger werden, während der Preis für die Windows Virtuellen Maschinen um 27 Prozent gesenkt wird.

Ab dem heutigen Tag wird es für Compute bereits eine neue Basic-Konfiguration geben, die der Standardinstanz sehr ähnlich ist, jedoch um 26,67 Prozent günstiger ist.

Pünktlich zur Build-Konferenz unterstreicht Microsoft damit das Streben immer mehr auf Cloudtechnologien zu setzen. Auch die Bereitschaft günstige Preise für ihre Kunden anzubieten ist durch diese und auch bereits in der Vergangenheit getätigte Preisreduzierungen sichtbar. Im Vergleich zu Amazon Web Services bietet Microsoft für die oben genannten Produkte mindestens den gleichen aber häufig auch einen günstigeren Preis an.

Mehr Infos dazu erhalten Sie unter http://blogs.msdn.com/b/windowsazure/archive/2014/03/30/microsoft-azure-innovation-quality-and-price.aspx.

 

 

Karsten Kempe: Auszeichnung als MVP für Visual Studio ALM

mvp2Yeaaaahaaaaaa!!! Gestern habe ich von Microsoft die Nachricht erhalten, dass ich als Microsoft Most Valuable Professional (MVP) ausgezeichnet wurde. Damit bin ich Teil einer kleinen Gruppe von Visual Studio ALM-Experten, die von Microsoft für ihr Engagement und ihre Unterstützung der technischen Communities mit diesem Award geehrt wurden.

Folgende Nachricht erreichte mich gestern bei Mail und ich musste Sie mehrmals lesen, bis ich Sie geglaubt habe:

MVP_Ernennung 

Die Bezeichnung Visual Studio ALM steht für Microsofts Application Lifecycle Plattform und deren Produkte, wie z.B. Visual Studio, Visual Studio Online, Team Foundation Server und einigen mehr.

Ich freue mich wirklich riesig und bin mega stolz Teil dieser Community zu sein. Ich bedanke mich bei Allen, die mich dabei unterstützt haben!!!

Mehr zum MVP-Programm gibt’s unter: http://mvp.microsoft.com/de-de/default.aspx

Klaus Aschenbrenner: Goodbye SQL Server, Hello FileMaker…

The last weeks were very time consuming for me, because I had to make a very tough decision: staying independent and providing high quality SQL Server consulting and training services, or getting employed (again), and being part of a greater team to influence how the IT industry will be in future.

After a very long thinking time, I have made my decision, and joining starting today – on April 1 – Apple. I will be the lead architect for FileMaker, the relational database on the Apple platform. I will be in charge of the whole dev team, leading the various development teams in FileMaker and also coordinate the necessary changes within Mac OS X. Our goal will be the integration of FileMaker within the OS, making HFS a transactional file system – the vision of WinFS, which was discarded by Microsoft…

Why me? I have a lot of experience in the area of relational databases (I know how to write basic SELECT * queries, which was also the toughest part of the SQLMCM certification). And of course the another most important factor why Apple has chosen me over other candidates is my hands-on experience in writing operating systems. As you might know, I have written my own OS, which boots from a FAT12 partition (I have found some code somewhere in the Internet…), reads a key from the keyboard, and writes it out. Everything done in x32 Protected Mode, without any BIOS calls! Impressive, huh? Apple was really amazed by that piece of software, therefore we will also evaluate if that code can be used as the future basis for Mac OS X 15.1.

Of course, Apple screened a lot of different candidates for this position, and I had a very hard competition. In the final round we were only 3 people, and I was feeling like someone in the TV show “Deutschland sucht den Superstar” (Germany searches for the super star). I never heard anything about the other 2 persons, the 1st one was a guy called Bob, and the name of the other one was Conor.

Bob performed really amazing, but he had too less low-level experience. To understand that a little bit better, I want to give you an example: one task that we had to perform during the final round was to join 2 tables together. Very simple task when you know the concept of a cartesian product. But Bob was opening WinDbg, and was doing everything with a graphical hex-dump. He violated the rules, because we were not allowed to use any GUI front-end… And Conor? He talked the whole day about trees, and cardinality estimations… So my solution with the cartesian product was chosen over their approaches. I`m the lucky one!

So wish me luck in my new role, and let´s change the way how relational databases are working.

Thanks for reading and a happy 1st April!

-Klaus

ppedv Team Blog: Webseiten mit Bild-Slider

Immer mehr (so beginnt jeder gute Artikel in einer Frauenzeitschrift) Webseiten beinhalten einen Image Slider. Und immer mehr gewinne ich den Eindruck, dass der aktuelle HTML5, CSS, JS-Weg das wiederholt was zu Visual Basic 4-Zeiten passiert ist: Komplexität in OCXen Widgets zu verstecken. Mein neuestes Fundstück ist in Bootstrap das Carousel.

Das Carousel Widget aus Bootstrap 3 kann ein oder mehrere Bilder durch Sliding-Effekte wechselnd darstellen. Da man mit HTML arbeitet, muss es kein Bild sein, sondern kann alles sein, was in ein DIV so passt (Item). Zur Steuerung bzw. zum direkten Sprung kann der Benutzer den Indikator verwenden. Dieser kann direkt wie ein Pager benutzt werden oder auch mit einer Next-Logik versehen werden. Dies macht Sinn, wenn es wesentlich mehr Bilder sind. Außerdem befindet sich rechts und links ein Carousel-Control. Dazu kommt eine Überschrift, die auch außerhalb des Bild-Bereiches platziert werden kann.

image

Das Ganze als HTML. Mit den Attributen wird Intervall in Millisekunden, und das Verhalten am Ende der Bild-Liste gesteuert.

Die Indikator-Elemente werden als direkte Navigationselemente verwendet.

   1:      <div class="carousel slide" id="carousel-example-generic"
data-ride="carousel" data-interval="3000" wrap="true">
   2:         
   3:          <ol class="carousel-indicators">
   4:              <li data-slide-to="0" 
data-target="#carousel-example-generic"></li>
   5:              <li class="active" data-slide-to="1" 
data-target="#carousel-example-generic"></li>
   6:              <li data-slide-to="2" d
ata-target
="#carousel-example-generic"></li>
   7:          </ol>
   8:   
   9:          <div class="carousel-inner">
  10:              <div class="item">
  11:                  <img alt="PX" src="img/px.png">
  12:                  <div class="carousel-caption">
  13:                      <h3>Vespa PX 200E</h3>
  14:                      <p>Modernere Bauart</p>
  15:                  </div>
  16:              </div>
  17:              <div class="item active">
  18:               <a href="http://www.ppedv.de">
  19:                  <img alt="LX" src="img/lx.png"></a>
  20:                  <div class="carousel-caption">
  21:                      <h3>Vespa LX</h3>
  22:                      <p>jüngere 50er und 125er</p>
  23:                  </div>
  24:              </div>
  25:              <div class="item">
  26:   
  27:                  <img alt="GS" src="img/gs.png">
  28:                  <div class="carousel-caption">
  29:                      <h3>Vespa GS 150</h3>
  30:                      <p>alter Klassiker</p>
  31:                  </div>
  32:              </div>
  33:          </div>
  34:   
  35:         
  36:          <a class="left carousel-control" 
href="#carousel-example-generic" data-slide="prev">
  37:              <span class="glyphicon glyphicon-chevron-left"></span>
  38:          </a>
  39:          <a class="right carousel-control" 
href="#carousel-example-generic" data-slide="next">
  40:              <span class="glyphicon glyphicon-chevron-right"></span>
  41:          </a>
  42:      </div>

Natürlich lässt sich per CSS das visuelle Erscheinungsbild noch verändern. Da die Styles natürlich in bootstrap.css vordefiniert sind, muss die Definition nachgelagert erfolgen.

   1:    <style>
   2:          .carousel-caption {
   3:              position:absolute;
   4:              top:-10px;
   5:              left:auto;
   6:              right:20px;
   7:              bottom:0;
   8:              height: auto;
   9:              z-index: 30;
  10:              background: none;
  11:          }
  12:   
  13:          .carousel-indicators {
  14:              top: 20px;
  15:          }
  16:   
  17:              .carousel-indicators li {
  18:                  width: 12px;
  19:                  height: 12px;
  20:                  margin: 0 3px;
  21:                  background: #555;
  22:                  opacity: 0.3;
  23:                  border: none;
  24:                  transition: all 0.3s;
  25:              }
  26:   
  27:                  .carousel-indicators li.active {
  28:                      width: 12px;
  29:                      height: 12px;
  30:                      margin: 0 3px;
  31:                      opacity: 1;
  32:                      background-color: #555;
  33:                  }
  34:      </style>

Warum erinnert mich das an die VB-Zeiten? Damals sprangen unzählige Control-Hersteller in die Unzulänglichkeiten von Microsoft ein. Schon mit Releasewechsel waren die Controls nicht mehr funktionsfähig. Die allermeisten Hersteller existierten nur sehr kurz. Ein Control in einem Projekt durch ein anderes zu ersetzen überstieg den Aufwand der ursprünglichen Implementierung. 

Was ist der Unterschied, VB 6-Anwendungen laufen auch noch nach 10 Jahren. Das wird keiner mit einer Bootstrap, JQuery und sonst was basierten Seite auch nur 2 Jahre schaffen.

ppedv Team Blog: ‘LESS’-CSS is more than you may think…

Wie der Titel schon verrät, werden wir in diesem Beitrag einen der CSS-Precompiler mal genauer unter die Lupe nehmen. Einfach gesagt kann man sich das ganze wie eine Feature-Erweiterung betrachten. Wir erhalten die Möglichkeit Variablen, Funktionen uvm. in unseren zukünftigen CSS-Files zu verwenden und uns somit das Leben enorm zu erleichtern. Oft hört man den Spruch “Jeder, der CSS mag, hat doch nicht mehr alle Tassen im Schrank”. Ich für meinen Teil mag CSS, besonders durch das neue VS2013 & die WebEssentials macht das ganze wieder richtig Spaß. Ich stoße jedoch oft an Punkte, wo mich die Sehnsucht nach Variablen oder derartigen Methoden packt. Und genau dafür ist LESS zuständig.

Vorab ist es vielleicht noch wichtig zu erwähnen, dass wir im VisualStudio 2013 und 2012 (mit WebEssentials) bereits einen LESS-Compiler mit integriert haben und sogar eine super Ansicht über das daraus gerenderte CSS.

clip_image002

Links: LESS Code | Rechts: CSS Output (nicht editierbar)

In diesem Bild sehen wir eine geöffnete LESS-Datei im VisualStudio (2013 oder 2012 + WebEssentials) und dem daraus entstandenen CSS-File. Das praktische an der ganzen Sache ist folgendes: VS erstellt automatisch eine dazugehörige CSS-Datei und hält diese immer up-to-date. Also müssen wir nicht immer z.B. extra einmal einen Build ausführen oder derartiges. Sogar eine minified Version des Ganzen wird uns zur Verfügung gestellt. Ohne VS müsste man das Ganze on-the-fly kompilieren, für jeden erneuten Request, was nur unnötig Zeit verbrauchen würde.

clip_image004

Variablen

Variablen in LESS lassen sich extrem einfach erstellen und verstehen.

clip_image006

Der Wert, welchen wir dieser Variable nun zuweisen, ist komplett uns überlassen.

ob Farben…

clip_image008

Schriftarten(strings), Pixelangaben, oder das Zuweisen anderer Variablen…

clip_image010

…alles ist möglich. Dadurch lassen sich auch wunderbar sogenannte Abstraktions-Ebenen erstellen, um den Code wiederverwendbarer zu halten:

clip_image012

 

Nested Rules (CSS inheritance)

Durch Nested Rules können wir bereits verwendete CSS-Konstrukte in andere einbinden und dadurch wiederverwenden.

clip_image014

Wie wir sehen werden ‘btn’ als auch ‘btn-default’ ganz normal gerendert. Jedoch enthält btn-default alle Eigenschaften von 'btn'.

Ein gutes Beispiel bzw. guter Anwendungsfall hierfür wäre die allseits bekannte Navigation.

clip_image016

Das ‘&’ vor der :hover Pseudo-Klasse steht für alle vorhergehenden Selektoren und wird zu ‘ul#nav li a:hover’ gerendert’ was auch wiederum enorm viel Getippe spart.

Problem hierbei, wenn wir die Nested Rule als Art Basis-Klasse verwenden wollen, stellen wir bald fest, dass diese immer mit gerendert wird. Das heißt, dass es unter Umständen unnützer CSS-Code erstellt wird.

 

Mixins (Funktionen)

Diese Mixins sehen aus wie ganz normale CSS-Klassen, haben aber noch die Option Parameter mit zu übergeben. Diesen Parametern kann man sogar noch Default-Werte verpassen, wenn man das möchte.

clip_image018

Interessant hierbei: das Mixin selbst erzeugt keinerlei CSS und lässt dieses am Ende dadurch schlanker wirken und kann nun beliebig oft verwendet werden.

 

Funktionen & Berechnungen

Ja endlich! Darauf wartet wahrscheinlich jeder CSS-Tüftler schon sein Leben lang! Endlich sind wir in der Lage einfache bis komplexe Rechenoperationen zu verwenden.

clip_image020

Wie man sieht, können wir nicht nur einfache Werte miteinander addieren, subtrahieren, multiplizieren oder dividieren. Wir können sogar mit HEX-Codes Berechnungen durchführen. Selbstverständlicherweise nur + und –. Hierbei ist anzumerken, dass + oder - #000 immer als 0 gehandhabt wird und + #fff immer in #ffffff (weiß) endet als auch - #fff immer in #000000 (schwarz) endet.

Dazu kommen noch spezielle Funktionen, welche uns den Umgang mit Farben im Allgemeinen erleichtern sollen bzw. die Berechnung dieser.

clip_image022

Lighten und Darken sind, denke ich, selbsterklärend. Saturate steht für Sättigung. Jede dieser drei Funktionen bekommt als zweiten Parameter einen Prozentwert übergeben (0-100).

Spin hingegen ‘verschiebt’ die Farbe um einen gewissen Wert auf dem Farbenkreis und kann somit maximal Werte von 0-360 annehmen. Alles was darüber hinausgeht führt zu einer weiteren Umdrehung.

clip_image024

Quelle: Wikipedia - http://de.wikipedia.org/wiki/Farbkreis

 

Fazit

Sieht ganz so aus als ob wir in Zukunft ein neues Spielzeug haben :-)

Generell ist diese CSS-Precompiler-Geschichte eine recht interessante Sache und kann schon mit relativ einfachen Mitteln durchaus effektiv genutzt werden. Jedoch soll an dieser Stelle angemerkt werden, dass dies nur ein minimaler und kurzer Auszug aus der gesamten Funktionalität von LESS sein sollte, um einen kleinen Vorgeschmack darauf zu geben und evtl. Lust auf mehr zu machen.

Für alle, die sich die Sache noch intensiver anschauen möchten, empfehle ich die offizielle LESS-Website. Auf dieser befindet sich eine Doku mit Beschreibung & Beispielen.

Holger Schwichtenberg: Live-Übertragung von Microsofts BUILD-Konferenz

Microsoft überträgt diese Woche wieder live die Vorträge, in denen die Neuigkeiten rund um Windows, Azure, .NET und Visual Studio präsentiert werden.

ppedv Team Blog: IIS 7/7.5 - Neuerungen

Mit Windows Server 2008 und Windows Vista erblickte der IIS 7 (Internet Information Service 7) die Welt. Die neue Oberfläche und das neue Bedienkonzept standen hier an oberster Stelle. Mit Windows Server 2008R2 bzw. Windows 7 steht der IIS 7.5 zur Verfügung, der speziell in den Bereichen Performance, Stabilität und Sicherheit mit Neuerungen glänzt. So wurde beispielsweise die PHP-Unterstützung mit Hilfe von FastCGI verbessert. Hier nun alle wichtigen Neuerungen im Vergleich zum IIS 6:

Neue Bedienoberfläche
Mit dem IIS 7 wurde eine komplett neue Bedienoberfläche eingeführt, die auf einer verteilten und delegierten Verwaltungsarchitektur basiert. Sie ermöglicht eine flexiblere Konfiguration des Webservers und der Websites.

iis6 iis7
Die Bedienoberfläche des IIS 6 und IIS 7.5 im Vergleich

Modularer Aufbau
Ab Version 7 ist der IIS modular aufgebaut. Bei der Installation kann genau ausgewählt werden, was der IIS können soll oder nicht. Ziel ist es natürlich, den IIS so “schlank” wie möglich zu halten. Folgende Module stehen zur Verfügung:

- Allgemeine HTTP-Features
- Anwendungsentwicklung
- Integrität und Diagnose
- Sicherheit
- Leistung
- Verwaltungsprogramme
- FTP-Server
- Hostfähiger IIS-Webkern

Integrierter Modus
Mit dem sogenannten “Integrierten Pipelinemodus” gewinnt der IIS in Sachen Performance und Stabilität. So können jetzt beispielsweise ASP.NET-Anwendungen über ein integriertes Modul abgearbeitet werden, anstatt die Aufgabe einem “externen” ISAPI-Filter zu überlassen.

Diensthärtung (IIS 7.5)
Mit Hilfe des Isolationsmodells von Anwendungspools kann die Zuverlässigkeit und Sicherheit deutlich gesteigert werden. Es werden jetzt alle Anwendungspools in separate Windowsprozesse standardmäßig mit einer niedrigeren Identität ausgeführt.

Anforderungsfilterung (IIS 7.5)
Um evtl. gefährliche Anforderungen zu filtern, bevor diese den Server erreichen, steht nun die Anforderungsfilterung zur Verfügung. Hier können Anfragen beispielsweise anhand der Dateinamenerweiterung oder des HTTP-Headers gefiltert werden.

Hostfähiger Webkern
Kernkomponenten des IIS-Webmoduls können hiermit von anderen Anwendungen benutzt werden. So kann der IIS HTTP-Anfragen von diesen Anwendungen direkt bearbeiten.

IIS-Modul für die Windows PowerShell
Über das IIS-PowerShell-Modul kann der IIS über Windows PowerShell installiert und verwaltet werden.

Klaus Aschenbrenner: SQL Server Quickie #12 – Nested Loop Operator

(Be sure to checkout the FREE SQLpassion Performance Tuning Training Plan, where you are getting week by week via email all the essential knowledge you need to know about performance tuning on SQL Server.)

Today I have uploaded the 12th SQL Server Quickie to YouTube. This time I’m talking about the Nested Loop Join Operator in SQL Server. You can find the script used during the demonstration here as a download.

Thanks for watching!

-Klaus

ppedv Team Blog: EU Cookie Opt-in

Als wenn wir nicht schon genug Regeln hätten, gibt es seit 2009 die Richtlinie 2009/136/EG. Es wird viel geschrieben darüber und ich bin kein Experte. Es scheint so zu sein, dass jeder Staat eine eigene Umsetzung vorweisen muss. Kurz zusammengefasst geht es dabei um Datenschutz. Genauer um personenbezogene Daten.

Darunter fallen auch Tracking Cookies wie von Google Analyze. Ich bin ohnehin kein Freund davon, aber auch Piwik setzt Tracking Cookies ein. Solange dies für den Betrieb der Website notwendig ist, wie Authentifizierung oder Passwort, sollte auch keine Einwilligung des Benutzers nötig sein. Für alles andere muss er zustimmen bzw. die Möglichkeit haben dies abzulehnen.

Die EU fordert ein Opt-in Verfahren.

An vielen Stellen wird über Sinn oder Unsinn diskutiert. Letztendlich kann jeder in seinem Browser Cookies deaktivieren oder mittels inprivate Browser löschen.

image

Es ist eine dumme und ungenaue Regelung, die allerdings mit Strafe belegt ist. Und es kommt sicherlich auch bald einer der unzähligen Anwälte darauf Abmahnungen zu schreiben.

Also habe ich mich daran gesetzt und ein paar Zeilen JavaScript-Code geschrieben, der unabhängig von HTML und CSS ist. Sogar auf JQuery habe ich verzichtet.

   1:    <script>
   2:              window.onload = function () {
   3:                  var optin;
   4:                  var ca = document.cookie.split(';');
   5:                  for (var i = 0; i < ca.length; i++) {
   6:                      var c = ca[i].trim();
   7:                     if (c.indexOf('EUCookie') == 0) optin = true;
   8:                  }
   9:                  if (optin != true)
  10:                  {
  11:                      var ele = document.createElement("div");
  12:                      ele.setAttribute("id", "optincookie");
  13:                      ele.setAttribute("style", "width:100%;height:30px;opacity:0.3;
z-index:100;background:#000;"
);
  14:                      ele.innerHTML = "<p style='color:white;display:inline-block;
margin:5px;'>You accept Cookies</p><a href='datenschutz.aspx' >details</a>
<img style='padding:2px;' src='/img/close.png' id='closecookie'/>"
;
  15:   
  16:                      document.body.insertBefore(ele,document.body.childNodes[0]);
  17:                      var mylink = document.getElementById('closecookie');
  18:                      mylink.onclick = function (e) {
  19:                          document.body.removeChild(ele);
  20:                          var d = new Date();
  21:                          d.setTime(d.getTime() + (90 * 24 * 60 * 60 * 1000));
  22:                        
  23:                          document.cookie = "EUCookie=yes; " + "expires=" + d.toGMTString();
  24:                      };
  25:                  };
  26:              };
  27:   
  28:   
  29:          </script>
  30:        

Ein wunderbarer Anlass mich daran zu erinnern wie grottig ich JavaScript eigentlich finde. Am Stil erkennt man vermutlich, dass ich das vor rund 20 Jahren gelernt habe.

Noch ein sehr kritisches Wort zum Wettbewerbsrecht. Impressum, Datenschutzerklärung, Widerrufsrecht, Urheberrecht und vieles mehr dient vor allem den Anwälten. Ausländische Unternehmen scheren sich einen Dreck darum. Wer seinen Sitz in Deutschland hat und eine Website betreibt, kann unmöglich juristisch korrekt Geschäfte machen. Je größer und gewinnbringender der Website-Betreiber desto lukrativer ist es einen Rechtsstreit anzufangen. 30% der deutschen Abgeordneten sind Juristen.

Ein noch kritischeres Wort zur Gesetzgebung und zur EU. Offensichtlich finden die unzähligen gut bezahlten EU-Parlamentarier ihre Berechtigung darin, eine noch strengere Regelung voranzutreiben. Ein Frauenquote da, eine Datenschutzregel dort.

Ach ja wenn es um Datenschutz geht, ist das Ankaufen von gestohlenen CD’s völlig ok, auch der Verkauf von Meldedaten, der Zugriff auf Kontodaten und das Abhören von uns allen.

ppedv Team Blog: Office Web Apps – Leider ging etwas falsch. Technische Details

Machen Sie so etwas nie! Wenn Sie diese Meldung in Sharepoint 2013 bei den Office Web Apps bekommen oder etwa Access Services 2013 Lösungen nicht veröffentlichen können, dann steht vermutlich oben im Eck der Sharepoint-Seite:

SYSTEMKONTO

Der Fehler tritt auf, da die Office Web Apps beim SharePoint-Server einen Benutzertoken bei jeder Anforderung übergeben müssen. Jedoch erstellt SharePoint Server 2013 kein Benutzertoken für ein Systemkonto. Also auch kein Konto bzw. Token für die Office Web Apps.

Verwenden Sie ein anderes Konto und schon wird wieder alles funktionieren Zwinkerndes Smiley

Also liebe Installateure, die das DOM\Administrator-Konto für die Testfarm verwenden. Das steht auf den 10 Geboten für den Sharepoint Server ganz oben.

Nachzulesen unter: http://support.microsoft.com/kb/2761265/de

ppedv Team Blog: Sharepoint 2013 und Office Web Apps – Probleme mit der Powershell

Die Office Web Apps Installation ist  keine besondere Herausforderung bei der Installation. Lediglich ein Punkt ist mir immer wieder aufgefallen, auf den ich hier mal hinweisen möchte. Ein Punkt, der mir dann und wann auch unter Sharepoint 2013 und Sharepoint 2010 unter die Finger gekommen ist. Vermutlich kennen Sie den Gedankengang: “das kenn ich doch schon, aber was war das denn..?” Nun hier die Lösung schriftlich zum Nachlesen für die Nachwelt.

Fehler bei der Verwendung von Powershell

Problem mit der Powershell
image
”Die Benennung .. wurde nicht als Name eines Cmdlets, einer Funktion, einer Skriptdatei .. erkannt." 

Simpler Grund: Die Powershell wird nicht in der korrekten Version ausgeführt. Sharepoint 2013 oder Office Web Apps erwarten die Version 3.0. Geladen haben Sie aber eventuell die Version 2.0.

Wie kann man seine Version feststellen?

Geben Sie dazu $PSVersionTable ein:

image

Für Sharepoint 2013 bzw. Office Web Apps ist die hier genannte Version 2.0  nicht geeignet. Das können Sie ganz leicht beheben, indem Sie entweder in der Powershell die geforderte Version laden oder die Verknüpfung schlichtweg ändern:

image

image

Kleine Änderung, große Wirkung.

ppedv Team Blog: Office Web Apps 2013 – Installation

Office Web Apps sind sehr einfach zu installieren und haben nur wenige Stolperfallen. Gut ausgerüstet mit den richtigen Powershellskripten sind die Office Web Apps innerhalb von 15 Minuten inkl. Installation und Skripten funktionsfähig.

Welche Etappen haben wir dazu vor uns:

  1. Vorbereiten des Office Web App Servers
  2. Installation der Office Web Apps
  3. Per PowerShell eine Office Web App Farm einrichten
  4. Unsere SharePoint-Farm per PowerShell mit der Office Web App Farm verbinden

So und nun mal der Reihe nach:

Vorbereiten des Office Web App Servers

Office Web Apps benötigen einen eigenen Server. Das bedeutet: Windows Server 2008 R2 SP1 oder höher ohne Office 2013 und ohne SharePoint-Installation. Also ein wirklich nackter Server! Der SharePoint Designer 2013 zählt hier logischerweise mit als Office-Produkt. Auf dem Server müssen je nach Betriebssystem verschiedenste Dinge an Board sein:

    und eine Reihe von Features müssen aktiviert werden. An dieser Stelle verweise ich auf folgende Skripte, da sie alle notwendigen Features auf dem OS aktivieren:
    Für Windows 2008:
Import-Module ServerManager
Add-WindowsFeature Web-Server,Web-WebServer,Web-Common-Http,Web-Static-Content,
Web-App-Dev,Web-Asp-Net,Web-Net-Ext,Web-ISAPI-Ext,Web-ISAPI-Filter,Web-Includes,
Web-Security,Web-Windows-Auth,Web-Filtering,Web-Stat-Compression,Web-Dyn-Compression,
Web-Mgmt-Console,Ink-Handwriting,IH-Ink-Support
 

Für Windows 2012

Add-WindowsFeature Web-Server,Web-Mgmt-Tools,Web-Mgmt-Console,Web-WebServer,
Web-Common-Http,Web-Default-Doc,Web-Static-Content,Web-Performance,Web-Stat-Compression,
Web-Dyn-Compression,Web-Security,Web-Filtering,Web-Windows-Auth,Web-App-Dev,Web-Net-Ext45,
Web-Asp-Net45,Web-ISAPI-Ext,Web-ISAPI-Filter,Web-Includes,InkandHandwritingServices,
NET-Framework-Features,NET-Framework-Core
 

Fertig mit Schritt 1

Nun kann die Installation der Office Web Apps folgen

Installation Office Web Apps

    Gelinde gesagt, sieht dies so aus:

image

Falls hier jemand Probleme hätte, kann er sich gerne melden Zwinkerndes Smiley

Günstigerweise installieren Sie an dieser Stelle das SP1 der Office Web Apps. Oder wer das noch nicht einsetzen möchte, dann zumindest das Update http://support.microsoft.com/kb/2810007/de

Konfigurieren der Office Web App Farm

Nun wird die Farm erstellt. Sie müssen dazu die PowerShell verwenden und unter Umständen noch die Offce Web Apps-Module nachladen

Import-Module -Name OfficeWebApps

New-OfficeWebAppsFarm -InternalURL "http://servername" -AllowHttp –EditingEnabled
 

Wobei AllowHTTP ohne Zertifikate arbeitet und EditingEnabled eine Lizenzierung der Clients mit Office 2013 erfordert.

Wollen Sie die Farm per Zertifikat absichern und nach extern veröffentlichen, dann verwenden Sie folgendes Script:

New-OfficeWebAppsFarm -InternalUrl https://intern.firma.de -ExternalUrl https://extern.firma.de 
-CertificateName "OfficeWebApps Certificate" –EditingEnabled
 

Wobei CertificateName den Namen des Zertifikats darstellt.

Ob das erfolgreich war läßt sich ganz gut testen:

Rufen Sie im Browser folgende Adresse auf:

http://ServerName/hosting/discovery

Erfolg sieht so aus:

image

SharePoint-Server mit Office Web App Farm verbinden

Auf dem SharePoint-Server führen Sie in der SharePoint-Verwaltungshell folgendes aus:

New-SPWOPIBinding -ServerName <WacServerName> –AllowHTTP
 

Wobei <WacServerName> dem Namen des Office Web App Server entspricht.

Set-SPWOPIZone -zone "internal-http"

Letzter entscheidender Schritt: Falls nun per HTTP ein Zugriff stattfinden soll, dann muss dies explizit auf dem SharePoint-Server erlaubt werden:

(Get-SPSecurityTokenServiceConfig).AllowOAuthOverHttp
 

Falls Sie hier ein False bekommen, müssen folgende Zeilen nicht ausgeführt werden.

$config = (Get-SPSecurityTokenServiceConfig)
$config.AllowOAuthOverHttp = $true
$config.Update()
(Get-SPSecurityTokenServiceConfig).AllowOAuthOverHttp
 

Nun sollte den Office Web Apps nichts mehr im Wege stehen..

Nun sollten Dokumente im Browser editierbar sein und in Bibliotheken oder bei Suchergebnissen als Preview zur Verfügung stehen.

image

 

ppedv Team Blog: Office WebApps 2013 - Lizenzierung

Office WebApps machen Sharepoint so richtig rund. OneNote, Word, Excel im Browser inklusive Editieren. Super.  Lizenzrechtlich verhält sich die Sache in etwa so:

Nur lesen kostet nichts. Schreiben kostet Office 2013 Lizenzen.

Genaueres dazu findet man auch beim Microsoft unter  http://technet.microsoft.com/de-de/library/ff431682(v=office.15).aspx mit folgendem Wortlaut:

“…

  • Nur anzeigen. Office Web Apps erlaubt standardmäßig nur das Anzeigen von Dateien. Diese Funktionalität wird kostenlos bereitgestellt.

  • Bearbeiten und anzeigen. Sie müssen eine Lizenz zum Bearbeiten erwerben, um die Bearbeitungsfeatures von Office Web Apps mit SharePoint 2013 verwenden zu können. Sie ermöglichen die Bearbeitung, wenn Sie eine Office Web Apps Server-Farm erstellen.

Unternehmenskunden, die über ein Volumenlizenzierungsprogramm für Office 2013 lizenziert sind, können lokal die Office Web Apps-Bearbeitung für SharePoint 2013 ermöglichen. Dadurch können Benutzer Office-Bearbeitungsfunktionen zu Hause oder an anderen Orten nutzen, an denen unter Umständen keine Office-Clients installiert sind. Bearbeitungslizenzen für Office Web Apps können nicht separat erworben werden.

Ausführliche Details zu Ihrer Lizenz finden Sie in den Microsoft-Software-Lizenzbedingungen, die bei der Installation von Office Web Apps Server angezeigt werden.

SharePoint 2013 stellt eine neue Lizenzerzwingung bereit, die mit Office Web Apps verwendet werden kann. Wenn Sie die SharePoint-Lizenzierung und anschließend die Office Web Apps-Bearbeitung aktivieren, können nur Benutzer, die über die entsprechende Lizenz ("OfficeWebAppsEdit") verfügen, Office-Dateien in einem Browser bearbeiten. Falls für Benutzer keine Office Web Apps-Bearbeitungslizenzen angewendet werden, wird nur das Anzeigen unterstützt. Weitere Informationen zur Funktionsweise der Lizenzierung in SharePoint 2013 finden Sie unter Konfigurieren der Lizenzierung in SharePoint Server 2013. Der Parameter EditingEnabled, der die Bearbeitung ermöglicht, wird unter New-OfficeWebAppsFarm sowie unter Set-OfficeWebAppsFarm beschrieben. …”

Folgendes erklärt ausserdem noch die Unterschiedliche Lizenzierung zwischen Externen Benutzern und Internen:

image

zu finden unter: http://blogs.technet.com/b/volume-licensing/archive/2013/05/22/how-to-license-office-web-apps-server.aspx

Es geht sicher noch komplizierter Zwinkerndes Smiley Also lassen Sie sich daher gut beraten.

ppedv Team Blog: Aus Windows Azure wird nun Microsoft Azure

Am 2. April wird aus Windows Azure nun Microsoft Azure. Damit soll besser reflektiert werden dass die Cloudplattform nicht eine reine Windowsplattform ist sondern auch Linux, Oracle Software, Hadoop unterstützt. Außerdem kann man nicht nur mit .NET sondern auch mit Java, Python oder Ruby seine Anwendungen für Azure schreiben. Die Umbenennung in Microsoft Azure soll somit Microsofts Strategie widerspiegeln eine Cloud für alle Microsoft Kunden und für alle Microsoft eigenen Businessanwendungen (OneDrive, Skype, Office 365, Bing, XBox Live, Dynamics) zu sein.

Azure ist auch die erste öffentliche Cloudplattform die es in China gibt. Microsoft ging eine Partnerschaft mit 21Vianet ein, dem größten chinesischen Datacenterprovider, um Azure in China verfügbar zu machen.

Im April wird auch dWindows Azure Active Directory Premium generell verfügbar werden. Damit besteht die Möglichkeit der Synchronisation von lokalen Active Diretories mit den Cloud Active Directories.

Viele Neuigkeiten auch die in der einen oder anderen Stadt am morgigen weltweiten Global Windows Azure Bootcamp gezeigt werden.

 

ppedv Team Blog: Ándale, Ándale der schnellste SQL Server in Mexico

SQL Server 2014 – In-Memory

Der neue SQL Server 2014 steht in den Startlöchern und wird am 1. April released. Mit ihm fallen uns viele neue Features anheim. Wie z.B. In-Memory Tabellen.

Was ist In-Memory?

Mit In-Memory besteht die Möglichkeit „Memory Optimized tables“ zu erstellen. Diese beschleunigen das Lesen und Schreiben der Tabelle, in dem sie sich nach dem Start des SQL Server sofort im Arbeitsspeicher befinden und nicht erst von der Festplatte gelesen werden müssen. Das bringt schon einmal einen enormen Fortschritt bei der Optimierung der Datenbank, umso weniger Lese- und Schreibvorgänge von der Festplatte umso besser. Nun stellt sich die Frage: Ist es denn so tragisch wenn man einen Lesevorgang mehr hat?
Naja das kommt nun auf die Lebenszeit der Seiten im Arbeitsspeicher an.

Wenn nun eine Tabelle mit einen Select-Statement aufgerufen wird, werden alle Seiten der Tabelle von der Festplatte in den Arbeitsspeicher geladen. Nun fallen aber die Seiten der Abfrage nicht sofort wieder aus dem Arbeitsspeicher, es sei denn der Arbeitsspeicher ist dementsprechend voll und eine andere Abfrage braucht die Speicher.

Wenn nun die In-Memory Variante benutzt wird, fallen die „Memory-Optimized tables“ Seiten nie aus dem Speicher da sie sich dauerhaft im Speicher halten. Letztendlich bedeutet das, die I\O bei In-Memory gegen Null geht.

Dieses Feature erinnert stark an die frühere Variante Tabellen im Speicher zuhalten. Die Rede ist von „DBCC PINTABLE“. Mit diesem Statement wurden Tabellen als fixiert markiert und somit waren sie dauerhaft im Arbeitsspeicher. Allerdings wurde diese Funktionalität sehr früh wieder entfernt da unerwünschte Nebeneffekte auftraten. Dazu zählte die Beschädigung des Pufferpools. In-Memory soll komplett neu entworfen worden sein und keine negativen Gemeinsamkeit mit DBCC PINTABLE aufweisen.

 

Inmemory

 

Datenbank vorbereiten

Bevor man In-Memory Tabellen nutzen will muss man seine Datenbank dementsprechend erstellen oder anpassen.

create database HKTest
on
primary (Name = [HKTest data],
filename = 'C:\data\HKTest.mdf'),
filegroup [IM_fg] contains memory_optimized_data
(name = [HKTest_mod_dir],
filename = 'C:\data\HKTest_fg')
log on (name = [HKTest_log], filename = 'C:\data\HKTest_log.ldf')
collate Latin1_general_100_bin2

Eine Filestream-Dateigruppe muss erstellt werden und die Collation auf Latin1_General_100_bin2 gesetzt werden.

Bestehende Datenbank anpassen:

alter database HKTest
add filegroup IM_fg contains memory_optimized_data;
go
 
alter database HKTest
add file (Name='hk_mod', filename= 'C:\data\HKTest_fg')
to filgroup hk_mod;
go
 
alter database [HKTest] collate Latin1_General_100_BIN2
go

 

SQL Server Neustart, wo sind meine Daten?

Gehen wir davon aus man benutzt In-Memory Tabellen und der SQL Server entscheidet sich aus irgendwelchen Gründen den Dienst zu quittieren. Was passiert mit den Daten in den Memory-Optimized Tabellen? Schließlich liegen diese vollständig im Arbeitsspeicher und RAM ist flüchtig.

Glücklicherweise werden die Daten einer Memory-Optimized Tabelle in einer extra definierten Filestream-Dateigruppe gespeichert, sodass nach dem SQL Server Neustart die Daten aus der Dateigruppe ohne unser Zutun wiederhergestellt werden. Außerdem werden Operationen mit „Memory-optimized Tables“ ins gleiche Transaktionslog geschrieben wie „disk-based“ Tabellen.
Die Protokollierung der Memory-Optimized fällt äußerst gering aus, im Gegensatz zu disk-based Tabellen. Bei einer Ermittlung der Größe des Transaktionsprotokolls kam bei Memory-Optimzed Tabellen ein Größe von 42MB zustande, bei einem Einfüge Vorgang von einer Million Zeilen. Die nicht Speicheroptimierte Tabelle schnitt nicht so gut ab. Bei gleicher Tabellenstruktur und derselben Anzahl der Datensätze kam die Protokolldatei auf 4, 1GB. Genauso sieht es mit der Ausführungszeit des Insert-Statements aus. Hier kann ebenfalls wieder die Speicheroptimierte Tabelle punkten, mit einer Ausführungszeit von ca. zwei Sekunden sticht sie die disk-based Tabelle die mit ca. vier Minuten unterwegs ist aus. Der Grund des enormen Unterschieds besteht darin das die disk-based Tabelle die neuen Datensätze in die jeweilige Datendatei schreiben muss, was natürlich IO verursacht. Da die Speicheroptimierte Tabelle vollständig im Speicher liegt, entsteht somit keine IO.

Wenn eine Tabelle mit der Option „Schema_Only“ erstellt wird ist sie nicht dauerhaft und wird auch nicht mitgeloggt. Das bedeutet diese Art der Tabelle befindet sich im Speicher und benötigt somit keine IO. Die Schema_Only Variante setzt beim Punkt Ausführungszeit noch einen drauf und ist noch schneller als die „normale“ memory-optimized Tabelle Nachteil: nach einem Serverneustart oder einem Failover sind die Daten verloren, doch die Tabellen werden neu erstellt. Diese Art von Tabellen eignen sich ideal um eventuell Abfrageergebnisse zwischen zu speichern. Diese Neuerung bietet ein gute Alternative für Temporäre Tabellen und Tabellenvariablen.

Vorteile gegenüber der Temporären Tabellen/Tabellenvariable:

Bei einer Temporären Tabelle entsteht IO sobald Daten in die Tabelle geschrieben werden.
Eine Tabellenvariable hat ebenfalls ein Problem, und zwar können die Zeilen in der Variable nicht geschätzt werden. Beides trifft auf eine Memory-Optimized Table nicht zu.

CREATE TABLE dbo.Ord
(OrdNo INT not null primary key nonclustered hash with (bucket_count=1000000),
OrdDate datetime not null,
CustCode nvarchar(5) not null)
with (memory_optimized=on, Durability = Schema_and_Data)
go


Mit dieser Syntax wird eine Memory-Optimized Tabelle erstellt.

CREATE TABLE dbo.Ord
(OrdNo INT not null primary key nonclustered hash with (bucket_count=1000000),
OrdDate datetime not null,
CustCode nvarchar(5) not null)
with (memory_optimized=on, Durability = Schema_Only)
go


Gleiche Tabelle mit Schema_Only gekennzeichnet.

Wichtig zu wissen ist das mindestens ein Index auf der Tabelle vorhanden sein muss, und zwar ein hash Index wie im oberen Beispiel oder ein Range Index. Zu beachten ist lediglich die Größe des bucket_counts, man sollte nämlich ca. das 2-fache der eindeutigen Wert nehmen. Was ist der bucket_count? Der Hash Index besteht aus einem Array von Zeigern.
Jedes Element des Arrays ist ein sogenannter bucket_count. Wie lässt sich nun die richtige Größe des bucket_counts bestimmen? Idealerweise sollte man sich hier an der Anzahl der eindeutigen Indexzeile orientieren.

create procedure dbo.OrderInsert
with native_compilation, schemabinding, execute as owner
as
begin atomic with
(transaction isolation level = snapshot,
language = N'English')
declare @i int = 0
   while @i <= 1000000
      begin
      declare @OrdDate datetime = getdate();
      insert into dbo.Ord (OrdNo, CustCode, OrdDate) values (@i, 'ALFKI', getdate());
      set @i += 1
      end
end

 

Hier wird eine natively compilied procedure erstellt, in der eine Million Datensätze in die Memory-optimized Tabelle eingefügt werden. Bei einer Million Einträgen habe ich deshalb den bucket_count auf 1000000 gesetzt.

Allerdings wird der angegebene bucket_count aufgerundet und zwar Bit-weise.

Bucket_count von 10000 ist nicht gleich 10000
Bucket_count von 10000 ist gleich 16384 ergibt 2^14

Problem bei zu viel Bucket_count: Umso höher der bucket_count umso mehr Speicher verbraucht die Speicheroptimierte Tabelle.

Beispiel in den Test:
Bei meinen Tests ist mir einmal der Fehler unterlaufen das ich mich beim bucket_count um eine 0 vertan habe, daraus resultierte das mein SQL Server Dienst den gesamten Speicher der Virtuellen Maschine vertilgte.

Problem bei zu wenig Bucket_count: Bei zu geringer Größe des bucket_counts ist die Leistungssteigerung dahin.

Beispiel bei zu wenig Bucket_count:
Der Einfüge Vorgang dauerte bei einem Bucket_count von 1024 und einer Million Datensätze, achtmal solange.

Wenn man den bucket_count nicht bestimmen kann, sollte man den Range Index benutzen, doch dieser wird erst in der CTP2 des SQL Server 2014 vorgestellt. Mal sehen was dieser mit sich bringt.

Natively Compiled Procedures

Diese neuartige Stored Procedure funktioniert nur in Verbindung mit einer Memory-optimized Tabelle. Sie hat einen entscheidenden Vorteil, sie wird kompiliert und nicht interpretiert. In-Memory Tabellen sind schnell, wer aber noch schneller unterwegs sein weil benutzt sie in Verbindung mit natively Compilied Procedures. Allerdings gibt es eine sehr lange Liste zu Statements die nicht in einer natively Compilied Procedure benutzt werden dürfen. Hier der Link: http://technet.microsoft.com/en-us/library/dn246937%28v=sql.120%29.aspx

Mit einer Natively Complied Procedure lässt sich zusätzlich das Lesen beschleunigen. Bei einem Lesevorgang von 10.000.000.000 Datensätzen legt die In-memory Tabelle eine Zeit von 28 Sekunden vor. Die Schema_Only Tabelle braucht dieselbe Zeit als die Schema_and_data da sie sich beide im Speicher befinden. Die gleiche Anzahl der Einträge mit einer disk-based Tabelle abzufragen wäre Irrsinn. Deshalb habe ich Anzahl der Abgefragten Datensätze ein bisschen nach unten geschraubt und zwar auf 1 Million. Bereits hier dauert die Abfrage 58 Sekunden.

Fazit

Mit In-Memory hat Microsoft wieder einmal ein Fortschritt in Richtung Geschwindigkeit gemacht. Bei Einfüge Vorgängen eine Leistungssteigerung um den Faktor 30 und bei den Schema_Only Tabellen sogar um den Faktor 60. Allerdings ist Vorsicht geraten bei In-memory Tabellen, bei meinen Tests musste ich ca. zehnmal meinen SQL Server Dienst beenden, da durch den Speicherverbrauch der SQL Server kein RAM mehr zur Verfügung hatte. Früher war Arbeitsspeicher noch teuer, heute nicht mehr, der Preis des Arbeitsspeichers ist rapide gesunken. Beim heutigen Stand kann man eine Server mit 32 Kernen und 1 TB RAM schon für unter 50000€ erstehen. Allerdings sollte nicht der Irrglaube entstehen das mehr Arbeitsspeicher alle Probleme löst. Mehr Arbeitsspeicher reduziert zwar die Wartezeit für Lesezugriffe, wirkt sich aber nicht auf die Wartezeit aus die benötigt wird um Schreibvorgänge auf die Festplatte zu tätigen. Außerdem muss sich die Datenbank nach dem Neustart eine Weile wiederherstellen um die Daten aus der Filestream-Dateigruppe wieder in den Arbeitsspeicher zu laden.

Möchtest du mehr zu SQL wissen, dann schau mal hier: http://www.ppedv.de/SQL

ppedv Team Blog: HTML5 Datei Upload mit ASP.NET

Manches geht viel einfacher als man glaubt. File Upload ist eine übliche Aufgabe in Web Anwendungen und das klappt super. Eine begeisternde kurz Beschreibung.

Bisher habe ich für einen Dateiupload immer einen ASHX Handler geschrieben. Braucht man aber nicht, klappt auch mit einer einfachen aspx Seite.

   1:  Imports System.IO
   2:  Public Class upload
   3:      Inherits System.Web.UI.Page
   4:      Protected Sub Page_Load(ByVal sender As Object, 
ByVal e As System.EventArgs) Handles Me.Load
   5:          If IsPostBack Then
   6:              UploadFile(sender, e)
   7:          End If
   8:      End Sub
   9:      Protected Sub UploadFile(sender As Object, a As EventArgs)
  10:          Dim fc = Request.Files
  11:          For i = 0 To fc.Count - 1
  12:              Dim upload = fc(i)
  13:              Dim fn = Server.MapPath(".\daten\") + Path.GetFileName(fc(i).FileName)
  14:              upload.SaveAs(fn)
  15:          Next
  16:      End Sub
  17:  End Class

 

Der VB.NET Code beschreibt sich eigentlich von selbst.

Für den Design Teil, wird zunächst die CSS Regeln definiert. Es wird ein Bereich angelegt, der sich blau bzw. rot und blau verfärben soll.

image

   1:  <style>
   2:          #uploadzone {
   3:              width: 100px;
   4:              border: dashed thin #999;
   5:              height: 200px;
   6:              text-align: center;
   7:          }
   8:   
   9:              #uploadzone.hover {
  10:                  border-color: #aaa;
  11:                  background-color: #9cd0fc;
  12:              }
  13:   
  14:              #uploadzone.error {
  15:                  border-color: #f00;
  16:                  background-color: #faa;
  17:              }
  18:      </style>
  19:      

 

Im HTML Teil wird nur ein DIV als Ziel für Drag und Drop definiert. Der kurze JavaScript Teil dient zum registrieren des Drop Events und für die Prüfung der Flle API Fähigkeiten.

   1:   <form id="form1" runat="server" enctype="multipart/form-data">
   2:          <div id="uploadzone">Datei Drag&Drop</div>
   3:      </form>
   4:      <script>
   5:          if (window.File && window.FileList && window.FileReader) {
   6:              var z = document.getElementById('uploadzone');
   7:              z.addEventListener('dragover', handleDragOver, false);
   8:              z.addEventListener('drop', handleDropFile, false);
   9:          }
  10:          else {
  11:              alert('Kein HTML5 File API Support!');
  12:          }
  13:      </script>

 

Ein relativ großer JavaScript Block kümmert sich um die visuelle Interaktion und führt letztendlich den HTTP Post aus.

   1:      <script>
   2:          var files;
   3:          function handleDragOver(event) {
   4:              event.stopPropagation();
   5:              event.preventDefault();
   6:              document.getElementById('uploadzone').setAttribute("class", 'hover');
   7:          }
   8:   
   9:          function handleDropFile(event) {
  10:              event.stopPropagation();
  11:              event.preventDefault();
  12:   
  13:              files = event.dataTransfer.files;
  14:   
  15:              var form = document.getElementById('form1');
  16:              var data = new FormData(form);
  17:   
  18:              for (var i = 0; i < files.length; i++) {
  19:                  data.append(files[i].name, files[i]);
  20:              }
  21:              var xhr = new XMLHttpRequest();
  22:              xhr.onreadystatechange = function () {
  23:                  if (xhr.readyState == 4) {
  24:                      if (xhr.status == 200) {
  25:                          alert("upload erfolgreich");
  26:                          document.getElementById('uploadzone').
setAttribute("class", '');
  27:   
  28:                      } else {
  29:                          document.getElementById('uploadzone').
setAttribute("class", 'error');
  30:   
  31:                          alert("fehlgeschlagen");
  32:                      }
  33:                  }
  34:              };
  35:              xhr.open('POST', "Upload");
  36:              xhr.send(data);
  37:          }
  38:      </script>

Golo Roden: Konsole & …: Verzögerte Ausführung

Umfangreiche Ergebnismengen zu berechnen, ist zeit- und speicheraufwendig. Das in JavaScript neu verfügbare Schlüsselwort yield hilft, dieses Problem zu lösen – und bildet zudem die Basis zur Implementierung von Koroutinen.

Klaus Aschenbrenner: The Illusion of Updateable Clustered ColumnStore Indexes

(Be sure to checkout the FREE SQLpassion Performance Tuning Training Plan, where you are getting week by week via email all the essential knowledge you need to know about performance tuning on SQL Server.)

In todays blog posting I want to concentrate in more details on the Updateable Clustered ColumnStore Index that is introduced with SQL Server 2014. Before we go down to the details, I want to give you a brief overview about their first appearance in SQL Server 2012, and their limitations.

ColumnStore Indexes in SQL Server 2012

The introduction of ColumnStore Indexes in SQL Server 2012 was one of the hottest new features (besides AlwaysOn). If chosen right, they can make an impressive performance improvement for Data Warehousing workloads. Unfortunately, they had 2 big limitations:

  • There was only the support for Non-Clustered ColumnStore Indexes
  • As soon as you had created a ColumnStore Index on a table, the underlying table was read only, and no changes to the data were allowed anymore

Both limitations were a huge bummer for some customers. Imagine you had a table with 300 GB of traditional row store data. With a ColumnStore Index it’s possible to compress that data down to a size of 30 GB. But SQL Server 2012 only allowed a Non-Clustered ColumnStore Index, means you had to store your data twice: one in the traditional row store format, and once in the new ColumnStore format. That’s a huge waste of storage, because your queries will (hopefully) only use your Non-Clustered ColumnStore Index.

And as soon as you had created your Non-Clustered ColumnStore Index, you were not allowed to change the underlying table data anymore – your table was just read only! Of course, there were some workarounds for this problem, like Partition Switching, but you still needed to implement that on your own…

ColumnStore Indexes in SQL Server 2014

Things are changing now with SQL Server 2014, because Microsoft has resolved the above mentioned issues – with some magic and illusion: SQL Server 2014 provides you an Updateable Clustered ColumnStore Index! Let’s have a more detailed look on how this magic and illusion happens internally in SQL Server.

The first most important fact is that an underlying direct update of a ColumnStore Index is not possible! It would be too time consuming to do the complete decompress and compress on the fly during your INSERT, UPDATE, and DELETE transactions. Therefore SQL Server 2014 uses help from some magic: Delta Stores and Delete Bitmaps. Let’s have a more detailed look on both concepts.

Every time when you run an INSERT statement, the new record isn’t directly inserted into the ColumnStore Index – the record is inserted into a Delta Store. The Delta Store itself is nothing else than a traditional B-Tree structure with all its pro’s and con’s. When you afterwards read from the ColumnStore Index, SQL Server returns you the data from the compressed ColumnStore Index AND also from the Delta Store.

When you run an DELETE statement, again nothing happens in the compressed ColumnStore Index. The only thing that happens is that the record is deleted logically through a Delete Bitmap. Every record in the ColumnStore Index has a corresponding bit in that Delete Bitmap. When you again read your ColumnStore Index, SQL Server just discards the rows that are marked as deleted in the Delete Bitmap.

And running an UPDATE statement just means inserting the new version into the Delta Store, and marking the old version as deleted in the Delete Bitmap. Easy, isn’t it? The following picture (source http://research.microsoft.com/apps/pubs/default.aspx?id=193599) shows this concept in more details.

ColumnStore

Because of the Delta Stores and the Delete Bitmap it seems that your ColumnStore Index is updateable, but in reality it is just immutable. There is also a background process called the Tuple Mover, which runs regularly and finally pushes your changes asynchronously into the compressed ColumnStore Index.

In addition you can also finally define a ColumnStore Index in SQL Server 2014 as Clustered. This means that you don’t need to have your data in the traditional row store format anymore. Just create your table and create a Clustered ColumnStore Index on it. You can some with this approach huge space savings in your storage, because everything is now compressed. When you work in more details with the concepts of relational databases, Clustered always means Sorted. But with a Clustered ColumnStore Index this statement is not true: when you create a Clustered ColumnStore Index, there is NO sorting order in your data! Just be aware of this tiny little fact ;-)

Summary

Updateable Clustered ColumnStore Indexes are a nice magical illusion of SQL Server 2014. Don’t get me wrong: I really like the possibilities introduced with this new feature, but you have to understand how the feature is implemented internally, if you want to make the best use of it.

Thanks for reading

-Klaus

Kay Giza [MS]: Grosses Gewinnspiel plus 2 Live-Webinare im Mai 2014

Gerne möchte ich auf zwei Live-Webcast im Mai 2014 aufmerksam machen. Die Webcasts finden mit einem parallel stattfindendem Experten-Chat statt, wo MVPs und Microsoft-Mitarbeiter sich freuen, Ihre Fragen zu beantworten. Flankiert werden die Webcasts mit einem großen Gewinnspiel mit über 100 Preisen! Jetzt kostenlos registrieren und doppelte Gewinnchance nutzen: Live-Webcast am 08. Mai 2014: Ende des Supports von Windows XP und Office 2003 sowie Live-Webcast am 22. Mai 2014: Office 365 - Die neue Art zu arbeiten Gewinnspiel - gewinnen Sie einen von über 100 Preisen! Unter allen... [... mehr in diesem Blogeintrag auf Giza-Blog.de]


This post is powered by www.Giza-Blog.de | Giza-Blog.de: RSS Feed
© Copyright 2006-2013 Kay Giza. All rights reserved. Legal

ppedv Team Blog: Testbericht Fujitsu T904

Seit über 10 Jahren verwende ich Tablet PC’s. Mit Windows XP Tablet Edition im Markt eingeführt und von Fujitsu Siemens als Lifebook T3010. Stift und Touch Eingabe mit drehbaren Display. Das Display war in den späteren Versionen sehr gut für außen und innen geeignet, damals noch entspiegelt. 

Abgelöst wird mein knapp 4 Jahre alter T900, mit Zweitakku, 256GB SDD und 8GB RAM. Top Performance, leider etwas schwer und leider auch schon mehrfach runtergefallen. Der Verschluss fürs Display hin, jede Ecke mit Heißkleber renoviert, aber Windows 8.1 installiert.

Das neue T904 kann Leistungsmäßig kaum mehr. Mit dem I7 Prozessor in der Maximalausstattung bei knapp über 2000€. Auch die Ausstattung Wlan, Fingerprint Scanner, UMTS Modem, GPS, Smart Card Reader waren schon im T900 enthalten. Nur mit den Treibern war es ein gefummle.

Immerhin sechs Monate musste ich von der Ankündigung bis zur Verfügbarkeit meines neuen Dauerbegleiters warten. Weg musste dafür das Surface Pro. Als Consuming Device nehme ich den Dell Tablet Venu 8 pro. Beide eint ein super Display mit hoher Helligkeit, die trotz Hochglanz auch außen fast immer lesbar ist.

Den Geräten ist auch die lange Akku Laufzeit gemein. Das T904 soll laut Hersteller über 8h schaffen. In meiner Anwendung mit Visual Studio waren es immer mindestens 6h. Die positive Überraschung war die Ladebuchse, ident mit allen älteren Modellen und weit verbreiteter Standard. Auch die Ladezeit ist extrem schnell. Das mitgelieferte Netzteil ist zwar klein nutzt aber ein Kabel mit Schutzkontakt. Deswegen verwende ich mein altes flaches Netzteil mit Rasiererstecker. Kleines Detail, aber unverzichtbar für mich, der Akku lässt sich einfach entnehmen. Darunter findet sich auch der UMTS Kartenleser.

Das Gerät ist wirklich leicht geworden, entsprechend dem INTEL Ultrabook Standard auch superflach, trotz drehbarem Display. Mit rund 1,5 kg die Hälfte des Vorgängers. Allerdings hat nun kein DVD Rom mehr Platz. Eine ausgefallene Klappkonstruktion musste sich die Ingenieure für die RJ45 Buchse einfallen lassen. Damit spart man es sich einen Adapter (wo ist der grad abgeblieben?) mitzuführen.

 

Weiters vorhanden 2x USB 3 (mehr wären besser). Das ist echter Knüller im Vergleich zum Vorgänger wenn man mal von einem USB 3 Stich kopiert. Ein HDMI statt VGA. Da muss ich wohl nun doch einen Adapter mitführen und eine Kombibuchse Speaker und Mikrophon.

Auf das extrem hochauflösende Display von  2560x1440 auf 13,3” mit 350cd/m² könnte ich gut verzichten. Es ist zwar vermutlich das Beste was aktuell am Markt so zu haben ist und muss sich vor keinem Apple Gerät verstecken. Aber.. Windows 8.1 kommt mit High DPI nicht wirklich klar. Dies liegt vor allem an den Softwareherstellern die ihre Programme anpassen müssten. Für mich sehr unangenehm ist der Betrieb mit dem externen Monitor. Die Probleme sind systematisch und nicht wenige schreiben in Ihren Blogs, das sie entsprechende Geräte wieder returniert haben. Nichts was man Fujitsu und Microsoft direkt anlasten kann.

Vorinstalliert ist Windows 8.1 das bei mir leider nicht 100% stabil läuft. Ich habe schon Bluescreen gesehen und der Fingerprint Scanner zeigt ab und zu keine Reaktion. Auch der Wlan Adapter ist spurlos verschwunden und erst nach Reboot wieder sichtbar gewesen.

Alles in allem keine uneingeschränkte Kaufempfehlung aber für meine Bedürfnisse das beste Gerät im Markt.

Martin Richter: Advanced Developers Conference zu native C++ in Münchem vom 29.-30.04

Wer das lange Wochenende zum 1. Mai auf ganz besondere Weise einleiten will, dem rate ich die ADC C++ Konferenz vom 29.-30.04.2014 in München zu besuchen.

Die Agenda enthält alt bekannte Themen, aber auch interessantes Neues. Nachdem mit C++x11, C++/RT wieder etwas Schwung in die Weiterentwicklung von C++ gekommen ist und auch die Geschwindigkeit in denen neue Compiler und Library Features veröffentlich werden beschleunigen, lohnt sich ein Blick über den Tellerrand.
Oft genug finden wir als Entwickler nicht die Zeit uns neuem zu widmen, dass bereits verfügbar ist oder in nächster Zeit verfügbar wird.

Veranstalter ist die ppedv AG (hinter der Johannes Preishuber steht). Ich habe die Konferenzen der letzten Jahre, an denen ich teilgenommen habe, immer in guter Erinnerung. Sowohl in der Auswahl der Themen und Redner, als auch in der exzellenten Durchführung, mit immer sehr schon gewählten Konferenzorten und Hotels.
Insofern lohnt sich sicherlich ein Blick in die Agenda.
Und ganz gespannt bin ich persönlich auf die Abendveranstaltung am Mittwoch, denn hier wird auf den ADC-Konferenzen den Teilnehmern immer etwas wirklich außergewöhnliches geboten.

Da ich letztes Jahr aus privaten Gründen leider nicht teilnehmen konnte freue ich mich dieses Jahr wieder dabei sein zu können; ,alte Kontakte beleben zu können, neue Entwickler kennen zu lernen und Neues aus der C++ Welt zu hören.

ADC


Copyright © 2010 Martin Richter
Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.
(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)

Falco Ostermann: Yammer and Office365 Integration with Service Pack 1 for SharePoint 2013

Mit dem Erscheinen des Service Pack 1 für die komplette Office Familie werden größtenteils Fehler behoben und die Performance gesteigert. Aber auch wird die Integration von Office 365 und weiteren Microsoft-Diensten vorangetrieben.

In SharePoint 2013 wird mit dem Service Pack 1 erstmalig Yammer und Office 365 integriert. Wie dies aussieht und ob die Integration gelungen ist, soll dieser Artikel etwas genauer beleuchten.

Yammer und Office365 Integration

Nachdem das Service Pack 1 erfolgreich auf dem SharePoint installiert wurde, erscheinen in der Zentraladministration neue Einstellungsmöglichkeiten.

Diese ermöglichen unter anderem das Verwenden von Yammer, anstelle des standardmäßigen SharePoint-Newsfeeds.

Dadurch wird der Newsfeed-Link in der Suitebar zu Yammer umbenannt.

Bei Klick auf den Link öffnet sich yammer.com in einem neuen Browser Fenster/ Tab, wo sich der Nutzer mit seinen Informationen anmelden muss.

Navigiert der Nutzer trotzdem zu seiner MySite, wo er vorher Newsfeeds abgegeben hat, so ist dies nach der Yammer Aktivierung nicht mehr möglich. Er kann lediglich bestehende Beiträge und Aktivitäten einsehen.

Für SiteFeeds auf den einzelnen Teamsites wird im Office Store eine eigene Yammer App für SharePoint angeboten. Diese kann mit wenigen Klicks installiert und auf der Seite platziert werden. Damit erfolgt auch diese Kommunikation über Yammer und wird entsprechend dort zentral gespeichert.

Neben Yammer wurde auch Office 365 mehr in die OnPremise-Welt von SharePoint 2013 integriert. Damit kann OneDrive for Business komplett auf Office 365 ausgelagert werden und blockiert keine internen Ressourcen mehr.

Bei einem Klick auf OneDrive in der SuiteBar, wird der Anwender zu der hinterlegten MySite auf Office 365 weitergeleitet.

Auch hier öffnet sich ein weiteres Browser Fenster/ Tab, wo der Nutzer sich mit seinen Office 365 Informationen anmelden muss. Anschließend befindet er sich im OneDrive des entsprechenden Office 365-Tenant.

Ein Navigationsweg zurück zur OnPremise-Welt gibt es leider nicht. Da aber ein eigenes Browser Fenster/ Tab geöffnet wurde, reicht es dieses wieder zu schließen.

Neben Yammer und OneDrive können auch die Sites ausgelagert werden. Dazu muss neben der MySite-Url lediglich der folgende Haken gesetzt werden:

Klickt der Anwender anschließend auf Sites in der SuiteBar, so öffnet sich auch hier ein weiteres Browser Fenster/ Tab mit der Umleitung auf Office 365.

Das Verhalten hierbei ist analog zur OneDrive for Business Auslagerung. Sprich auch hier muss der Anwender seine Anmeldeinformationen angeben, wenn er nicht schon angemeldet ist. Anschließend gelangt er zur MySite des entsprechenden Office 365-Tenant mit der  übersicht seiner dort gefolgten Seiten:

Fazit

Das Service Pack 1 bringt einige Neuerungen in Hinblick auf Yammer und Office 365 Anbindung mit sich. Jedoch kann dabei nicht von Integration gesprochen werden, da es lediglich zu den Diensten verweist. Sprich klickt der Nutzer auf Yammer, OneDrive oder Sites wird ein neues Browser Fenster/ Tab geöffnet in dem sich der Anwender zunächst anmelden muss. Auch gibt es keinen Navigationspfad zurück zur OnPremise-Welt. Da kann lediglich das neu geöffnete Browser Fenster/ Tab geschlossen werden.

Zwischen den Welten erfolgt auch kein Datenabgleich, wodurch die Anwender im Office 365 andere gefolgte Seiten sehen, als auf der OnPremise Umgebung. Auch unterscheiden sich die Activity Streams auf der MySite. Und das empfinde ich persönlich verwirrend, da dadurch auch Anwender Angst bekommen, Daten evtl. falsch abzulegen. Ich persönlich zweifel auch daran,dass viele OnPremise Kunden Ihre Kommunikation auf Yammer oder die internen Daten auf OneDrive for Business in Office 365 auslagern. Aber diese Diskussion möchte ich nicht hier führen.

Ich hoffe ich konnte euch einen visuellen Einblick in die Neuerungen des Service Pack 1 bringen und freue mich über euer Feedback :-) !

ppedv Team Blog: Walkthrough mobile ASP.NET Webforms

In diesem Blog wird gezeigt wie man in Minutenschnelle zu einem Web basierten Formular kommt.

Zunächst wird mit Visual Studio 2013 ein neues Web Projekt mit Web Forms erzeugt.

image

Dem Projekt werden per Nuget Paket Manager unter anderem das DynamicData Paket hinzugefügt. Dies wird dann für das Templating benötigt.

image

Weiters wird die JavaScript Erweiterung JQuery Mobile installiert.

image

Nuget erlaubt das aktualisieren aller installierten Paket wie Bootstrap oder JQuery. Das dauert am längsten.

image

Im nächsten Schritt wird ein Entity Framework Modell hinzugefügt. Dazu wird die Vorlage ADO.NET Entity Data Model benutzt.

image

Das Model wird aus einer im SQL Server vorhandenen Northwind Datenbank generiert.

image

Die Verbindung zum Datenbank Server muss konfiguriert werden. Nötige Parameter Server Name, Benutzer, Passwort. In diesem Screenshot wird die integrierte Authentifizierung verwendet.

image

Im nächsten Schritt wird definiert, das der Connection String dauerhaft in der Datei web.config abgelegt werden soll. Damit kann aus verschiedenen Stellen der Programmlogik darauf zugegriffen werden.

image

Im folgenden werden die Tabellen für das Modell ausgewählt. Im Beispiel die Tabellen Customers und Orders.

image

Das Modell wird gespeichert und das Projekt vorsichtshalber kompiliert. Im nächsten Schritt wir die ASPX Seite erzeugt bzw. dem Projekt hinzugefügt.

image

In den HTML Code der ASPX Seite wird ein FormView Control eingefügt. Mit Hilfe von Modelbinding wird zuerst (Zeile 3) der Itemtype definiert. Dann erzeugt Visual Studio beim erstellen von SelectMethod und UpdateMethod im Codebehind automatisch die Methodenrümpfe.

Besonderes Highlight ist das DynamicEntity Steuerelement das aus dem Datenmodell die Felder automatisch erzeugt.

   1:  <asp:FormView ID="FormView1" runat="server"
   2:        RenderOuterTable="false"
   3:        ItemType="WebApplication1Demo.Customers"
   4:        SelectMethod="FormView1_GetItem"
   5:        UpdateMethod="FormView1_UpdateItem"
   6:        DefaultMode="Edit"
   7:        DataKeyNames="CustomerID">
   8:        <EditItemTemplate>
   9:           <asp:DynamicEntity runat="server" Mode="Edit" />
  10:        </EditItemTemplate>
  11:  </asp:FormView>

Mit der Methode GetItem wird aus der URL der Parameter ausgelesen und damit auf dem Model in der Customers Tabelle der passende Schlüssel gesucht.

1: Public Function FormView1_GetItem(<FriendlyUrlSegments(0)> CustomerId As String)
As WebApplication1Demo.Customers

   2:          Dim nw As New NorthwindEntities
   3:          Return nw.Customers.Find(CustomerId)
   4:  End Function

Man kann es kaum glauben, aber nach knapp 2 Minuten existiert ein funktionsfähiges Formular.

image

Sieht noch nicht gut aus. Die Benennung der Felder, die Reihenfolge und auch die Validierungsregeln lassen sich über Metadaten im Model vorgeben. Fachausdruck DataAnnotations. Um diese dauerhaft zu definieren erzeugt man eine partielle Klasse mit identen Namen. Der wiederum weist man eine Metadaten Klasse zu in der dann die Attribute definiert werden.

   1:  Imports System.ComponentModel.DataAnnotations
   2:   
   3:  Public Class CustomersMetadata
   4:      <Editable(False)>
   5:      <Display(Name:="Kundennr")>
   6:      Public Property CustomerID As String
   7:      <Required(ErrorMessage:="erforderlich")>
   8:       <Display(Name:="Firma")>
   9:      Public Property CompanyName As String
  10:      <Display(Name:="Name")>
  11:      Public Property ContactName As String
  12:      <Display(Name:="Titel")>
  13:      Public Property ContactTitle As String
  14:      <Display(Name:="Adresse")>
  15:      Public Property Address As String
  16:      <Display(Name:="Stadt")>
  17:      Public Property City As String
  18:      <Display(Name:="Region")>
  19:      Public Property Region As String
  20:      <MaxLength(5, ErrorMessage:="zu lang")>
  21:      <Display(Name:="PLZ")>
  22:      Public Property PostalCode As String
  23:      <Required(ErrorMessage:="bitte füllen")>
  24:       <Display(Name:="Land")>
  25:      Public Property Country As String
  26:      <Display(Name:="Telefon")>
  27:      Public Property Phone As String
  28:      <Display(Name:="Telefax")>
  29:      Public Property Fax As String
  30:      Public Property LastChange As Byte()
  31:   
  32:      Public Overridable Property Orders As ICollection(Of Orders) = New HashSet(Of Orders)
  33:  End Class
  34:   
  35:  <MetadataType(GetType(CustomersMetadata))>
  36:  Partial Public Class Customers
  37:   
  38:   
  39:  End Class

Schon sieht das im Browser ganz gut aus. Die Kundennummer ist nicht mehr editierbar.

image

Jetzt fehlt nur noch die Möglichkeit die geänderten Daten auch zu speichern. Der Methodenrumpf für UpdateItem muss nur in Zeile 4-5 ergänzt werden und Zeile 14. Sekundenaufwand.

   1:   Public Sub FormView1_UpdateItem(ByVal CustomerID As String)
   2:          Dim item As WebApplication1Demo.Customers = Nothing
   3:          ' Element hier laden, z. B. item = MyDataLayer.Find(id)
   4:          Dim nw = New NorthwindEntities
   5:          item = nw.Customers.Find(CustomerID)
   6:          If item Is Nothing Then
   7:              ' Das Element wurde nicht gefunden.
   8:              ModelState.AddModelError("", 
String.Format("Das Element mit der ID {0} wurde nicht gefunden.", id))
   9:              Return
  10:          End If
  11:          TryUpdateModel(item)
  12:          If ModelState.IsValid Then
  13:              ' Änderungen hier speichern, z. B. MyDataLayer.SaveChanges()
  14:              nw.SaveChanges()
  15:          End If
  16:      End Sub

Letztlich fehlt noch der deklarative Teil im Web Forms Control. Zwei Buttons übernehmen per Commandname die Funktion.

   1:  <fieldset data-role="controlgroup" data-type="horizontal">
   2:  <asp:Button runat="server" ID="UpdateButton" 
CommandName="Update" Text="Update" />
   3:  <asp:Button runat="server" ID="CancelButton" 
CommandName="Cancel" Text="Cancel" CausesValidation="false" />
   4:  </fieldset>
 

War ganz einfach. Und das editieren und speichern klappt nun auch.

image

Optisch fehlt noch ein wenig, aber dafür kommt nun JQM zum Einsatz. Im HTML Code werden nur geringfügige Ergänzungen vorgenommen. Das Form (Zeile 7) die data-role und das Theme. Zeile 8 den Content Bereich. Zeile 18 die ControlGroup.

   1:     <link href="/Content/jquery.mobile-1.4.0.css" rel="stylesheet" />
   2:      <script src="/Scripts/jquery-2.1.0.js"></script>
   3:      <script src="/Scripts/jquery.mobile-1.4.0.js"></script>
   4:  </head>
   5:  <body>
   6:   
   7:      <form id="form1" runat="server" data-role="page" data-theme="a">
   8:          <div data-role="content">
   9:              <asp:FormView ID="FormView1" runat="server"
  10:                  RenderOuterTable="false"
  11:                  ItemType="WebApplication1Demo.Customers"
  12:                  SelectMethod="FormView1_GetItem"
  13:                  UpdateMethod="FormView1_UpdateItem"
  14:                  DefaultMode="Edit"
  15:                  DataKeyNames="CustomerID">
  16:                  <EditItemTemplate>
  17:                      <asp:DynamicEntity runat="server" Mode="Edit" />
  18:                      <fieldset data-role="controlgroup" data-type="horizontal">
  19:                          <asp:Button runat="server"
ID="UpdateButton" CommandName="Update" Text="Update" />
  20:                          <asp:Button runat="server"
ID="CancelButton" CommandName="Cancel" Text="Cancel" CausesValidation="false" />
  21:                      </fieldset>
  22:                  </EditItemTemplate>
  23:              </asp:FormView>

Sieht im Browser schon fast ganz fertig aus.

image

Problem entsteht wenn der Benutzer bei der Eingabe eine validierungsregel bricht. Der Benutzer sieht nur einen Stern und die Fehlermeldung nur wenn er die Maus über den Stern bewegt.

image

Ein ValidationSummary Control würde den Text anzeigen. Allerdings kann man auch in die DynamicData Templates eingreifen. Dafür sind sie eigentlich auch da. Der Ordner EntityTemplates wird vom DynamicEntity Control benutzt. Das DynamicControl nutzt dann wiederum abhängig vom Datentyp die UserControls aus dem Ordner Fieldtemplates.

image

Da es sich um ein Text im Edit Modus handelt, wird der VB.NET Code in der Datei text_edit.ascx.vb um die Zeilen 4-5 ergänzt.

   1:  SetUpValidator(RequiredFieldValidator1)
   2:  SetUpValidator(RegularExpressionValidator1)
   3:  SetUpValidator(DynamicValidator1)
   4:  RequiredFieldValidator1.Text = ""
   5:  RegularExpressionValidator1.Text = ""
   6:  DynamicValidator1.Text = ""

 

image

In diesem Walkthrough fehlen noch die Templates für Insert und die Funktionen für Delete und Insert. Diese sind aber analog sehr einfach zu realisieren.

ppedv Team Blog: ASP.NET Webforms Formulare 2014

User Interface Design hat enorm an Bedeutung gewonnen. Die Gestaltung von Dialogen folgt heute anderen Paradigmen. Im Webumfeld ist die mobile Nutzung treibende Kraft der Veränderung. Der Autor betrachtet die Anforderungen an ein Web basiertes Formular und eine mögliche Umsetzung mit ASP.NET Webforms.

Software Entwickler die die Anfänge der grafischen Benutzeroberflächen miterlebt haben, wissen das es vor allem um eines ging. Platz. Demzufolge findet sich fast immer eine Land-PLZ-Ort Kombination in einer Reihe. Worum geht es heute? Dazu stelle ich ein Reihe von Forderungen auf für das moderne Web 3.0 Formular und deren Erstellung.

-mobile Support

-effiziente Eingabe

-Tolerant

-billig in der Herstellung

Die Lebensituation des Web Workers lässt sich nur durch anketten an den Schreibtisch definieren. Für alle anderen Fälle müssen wir bereit sein. Vor allem die mobile Nutzung auf kleineren Screens und mit Touch Support. Um nicht für jeden Fall ein eigenes UI entwickeln zu müssen, bedarf es dem sogenannten Responsive Design Ansatz. Am einfachsten ist es, dazu ein UI Framework zu nehmen, wie Jquery Mobile.

Allerdings kann man dann keine Resolution optimized Screens designen. Wer das wirklich möchte, muss unter umständen für hunderte verschiedene Bildschirmgrößen HTML Code schreiben. Mit den CSS Media Breakpoints lassen sich zwar willkürliche Gruppierungen vornehmen ,um nur mehr eine Handvoll unterschiedlicher Formulare zu erhalten. Die Frage- ist der Aufwand den Erfolg wert?

Am einfachsten ist es sich, voll umfänglich in die Hände von Bootstrap und co zu begeben und nur mehr ein Formular zu pflegen. Die Kombination Land-Plz- Ort in einer Reihe ist dann obsolet und muss statt dessen Zeile für Zeile umgesetzt werden.

image

Wird der Platz weniger passt sich das Layout an.

image

Was ein Winforms Designer gelernt hat, verkehrt sich nun ins Gegenteil. Das Formular wird nach unten über den Bildschirmrand virtuell erweitert. Der Benutzer muss scrollen.

Verschiedene UI Elemente wie Textbox, Button oder Flip Toggle Switch sind leicht in jeder Situation bedienbar. JQM nennt diese Widgets.

image

Andere Controls sind schwer bis kaum bedienbar. Kalender, Treeview, Gridview. Es gibt Widgets für Kalender. Es gibt sogar einen Type Date im HMTL5 Standard der nur von Chrome entsprechend umgesetzt wird.

image

Jeder Use Case wird in einem anderen Szenario enden, ein Datum einzugeben. Ich bin durchaus Fan einer einfachen Textbox und nachgelagerter Validierung.

Vielleicht in Abbildung 1 bemerkt, ein x in jeder Zeile. Mit JQM einfach per HTML Attribut data-clear-btn="true" realisiert.

Effiziente Eingabe umfasst auch die Reduktion der Datenmenge. Suchdialoge leben dies schon eine Weile vor. Aus dem Verhalten des Benutzers seine Aktion abzuleiten und daraus Felder vor zu belegen. Oder noch besser gar nicht anzuzeigen, wenn die Daten nicht unbedingt nötig sind.

Gar nicht oft genug kann ich die Forderung nach gängigen Feldnamen zu stellen. Ein eMail Adresse muss immer ein name=”email” aufweisen um autocomplete nutzbar machen. Im folgenden Fall reicht die Eingabe der 8 um die komplette Postleitzahl (PLZ) vorgeschlagen zu bekommen.

image

Dies bezüglich ist ASP.NET Webforms auf den ersten Blick kein gutes Vorbild

   1:  <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
   2:   
   3:  wird zu HTML
   4:   
   5:  <input name="ctl00$MainContent$TextBox1" type="text" id="MainContent_TextBox1" />

Leider hilft das Attribut ClientIDMode=”Static” nur für die ID bzw wenn es sich um keine verschachtelten Controls handelt (Masterpage oder Usercontrol)

Bleibt nur noch die Frage, wie kann man für mehr Toleranz unter den Web Formularen sorgen?

Wikipedia

Toleranz, auch Duldsamkeit,[1] ist allgemein ein Geltenlassen und Gewährenlassen fremder Überzeugungen, Handlungsweisen und Sitten.

Hannes Preishuber

Gelten lassen der Benutzereingaben hinsichtlich Zeit und Inhalt.

Widersprüchliche oder falsche Daten dürfen nicht das ganz zerstören. Gültiges muss erhalten bleiben. Zeit darf keine Rolle spielen. Jeder hat die Erfahrung des leeren neu geladenen Formulars gemacht. Oder die Buchung des Zugtickets, bei der ein Anruf dazwischen kommt und man dann ganz von vorne anfangen muss.

Ein wichtiger Baustein dazu ist, keine Statusinformation am Server zu sichern. Die Session Variable muss durch eine URI ersetzt werden. Ein HTTP Endpunkt aus dem die Daten ermittelt werden, REST folgt dem gleichen Konzept.

Die URL setzt sich so aus der ASPX Seite (dem View wenn man so will) und der ID ( dem Action Parameter) des Datensatzes zusammen.

image

Die eigentliche SELECT Aktion wird über den HTTP GET Request zugewiesen. Erfreulicherweise ietet ASP.NET Webforms dies über die Funktion FriendlyUrls quasi automatisch. Dazu kommt Modelbinding. Hier wird im Code Behind oder einer eigenen Klasse (analog zum Viewmodel) je HTTP Methode einen Klasse angelegt. Die Get Methode akzeptiert unter anderem ein FriendlyUrlSegment als Parameter.

Letztendlich darf nur minimaler Aufwand nötig sein um zu einem solchen Massenprodukt wie ein Formular es ist zu kommen. Gerade der Erfolg von Access beruht darauf einen echten RAD Ansatz für Dateneingabe zu haben.  In Geschäftsanwendungen summiert sich deren Anzahl schnell auf eine dreistellige Anzahl. Folglich gilt so billig wie möglich.

Für den Walkthrough von der Datenbank über das Model bis zum Frontend werde ich noch einen eigenen Blog Eintrag verfassen. Dort wird gezeigt, wie man für einen LOB Anwendung sehr effektiv auch hunderte von Formularen in kürzester Zeit erstellt.

ppedv Team Blog: technische Ausstattung für Business Nomaden

Nicht alle meiner Blog Einträge müssen sich um SharePoint oder Business Intelligence drehen. Da ich aber in diesen beiden Bereichen Vorträge und Schulungen halte komme ich viel herum.

So habe ich gerade eine Vortragsserie für Microsoft beendet. Diese brachte mich immer Donnerstags abend nach München, Köln und nun nach Hamburg. Die Flugverbindung zurück nach Wien ist nicht ganz optimal und ich fliege erst am Abend wieder zurück. Leider hat die ppedv (noch) keinen Standort in dieser schönen Stadt und so verbringe ich nun einen Tag hier mobil und gehe dennoch meinem Job nach. Die moderne Technik macht es möglich. Wenn man entsprechend vorbereitet ist.

Im Laufe der Zeit konnte ich mein Gepäck optimieren um nur das notwendigste mitzunehmen. Ganz im Stil der Artikel in Airline- Magazinen:

Was habe ich dabei?

Notebook

Zunächst mal das Notebook: Lenovo x230 mit i7 und 16 GB Speicher. Außerdem sind 2 SDD Platten mit jeweils 256GB verbaut. Ich benötige für SharePoint auch unterwegs Performance. Die Abmessung des Notebooks sind möglichst klein. So kann ich auch im Flugzeug damit arbeiten.

WP_20140321_002

Internet

Für mich ist das wichtigste eine stabile Internetverbindung zu haben. Da ich einen österreichischen Handy Vertrag habe, ist die Nutzung der Internetfreigabe meines Handy fast unbezahlbar. Daher habe ich für Deutschland eine eigene SIM-Karte. Eigentlich hätte ich gerne einen Vertrag, aber leider bin ich als Österreich Ausländer. Und solange ich kein Bankkonto oder Wohnsitz (inkl Schufa Auskunft) habe, gibt es für mich keinen Vertrag. Die einzige Option sind Prepaidkarten.

Von der Firma habe ich eine Symio-Karte. Die hilft mir weiter, solange ich Empfang habe. Für jene Gegenden in Deutschland die noch nicht so erschlossen sind, habe ich eine Alternative. Mittlerweile habe ich O2, Vodafone und T-Mobile probiert und ich muss sagen, t-Mobile hat das beste Netz. Also nutze ich derzeit dieses. Ein Tag mit 500MB um 2,95 ist OK. zumal ich jederzeit untertags wieder ein Paket aktivieren wann um weitere 500BM zu erhalten. Bei symio geht das nur mit einer Zeitverzögerung von 2-4 Stunden. Das ist unpraktisch wenn ich genau jetzt!! mehr Datenvolumen benötige.

Nachdem ich mehrere Geräte dabei habe, möchte ich die Sim-Karte mit allen Geräten nutzen. Einfach ins Notebook stecken bringt hier nichts, da dann nur das Notebook versorgt wäre. Ich habe dafür einen kleinen UMTS  Router. (Huawei).

WP_20140321_001

In diesem steckt meine SIM Karte und meine Geräte wie Notebook, Handy und Tablet verbinden sich immer mit diesem WLAN. Praktischer weise habe ich diesen Router in der Hosentasche oder im Rucksack und kann so mein österreichisches Handy auch in Deutschland verwenden und erspare mir damit ein weiteres Handy mit zu nehmen. Im Hotelzimmer muss ich mich nicht erst mit dem Hotelnetz verbinden. Ich habe immer mein eigenes WLAN dabei. Ich bin mein eigener WLAN-Hotspot. Und an verregneten Hamburg Tagen habe ich in der Tasche auch eine Handwärmer. Das ding wird wirklich warm wenn es im Dauerbetrieb ist.

Stromversorgung

Das noch nicht perfekt gelöste Problem der Stromversorgung begleitet mich den ganzen Tag über. Das Notebook hat eine extra großen Akku dabei und hält somit wirklich 9-10 Stunden durch. Das reicht für meinen mobilen Arbeitstag. Aber Handy und WLAN –Router sind meine Sorgenkinder.

Mein oberstes Ziel ist, Gewicht zu sparen. Ich wiege jedes Teil das ich mitnehme mit der Küchenwaage ab. Daher nehme ich auch nicht unzählige Netzteile mit. Von Coolermaster habe ich ein Universal-Netzteil für Notebooks gefunden, welches nur 1,2 cm flach ist. Deutlich kleiner als das Original Netzteil von Lenovo. Außerdem ist ein USB Anschluss im Netzteil enthalten. Daher kann ich Notebook + ein USB Gerät mit nur einer Steckdose aufladen. Am Flughafen, in der Bahn und im Hotelzimmer ein Vorteil. Oft muss man glücklich sein, wenn man eine Steckdose findet. Selten sind gleich zwei oder drei Steckdosen frei.

Handy und WLAN Router verwenden als Ladekabel ein Standard USB Kabel. Zusätzlich habe ich zwei kleine Stromstecker mit USB Port im Rucksack. Damit bin ich flexibel womit ich welches Gerät auflade.

Leider muss mein Tablet (Samung Tab) mit einem speziellen Kabel geladen werden. Das ist ein dicker Minuspunkt für das Tablet und es wird ausgetauscht  sobald ich eines gefunden habe das über USB geladen werden kann.

Ich habe auch bereits mit einem Akku-Pack experimentiert um meine USB Devices zu laden. Aber die 900g sind mir zu schwer. Das Akku-Pack kommt nur noch am Segelboot in einsamen Buchten zum Einsatz.

Das wichtigste bei der Stromversorgung ist die Planung. So achte ich immer genau darauf im Hotelzimmer über Nacht alle Geräte aufzuladen.

Unterhaltung unterwegs

Um die Reise selbst möglichst angenehm zu gestalten haben ich mir angewöhnt immer mit Kopfhörer im Ohr unterwegs zu sein. Das muss nicht bedeuten dass ich immer Musik höre, aber meine Mitreisenden sollen das Gefühl haben, dass sie mich stören wenn sie mich anreden. Ich habe schon so viele Lebensgeschichten im Flugzeug gehört. Ich kenne sie mittlerweile alle.

Wer wirklich in Ruhe reisen möchte, dem lege ich die Investition in Bose-In-Ear-Noice Canceling Kopfhörer nahe. Ins Ohr, einschalten und es herrscht Ruhe. Die Umgebungsgeräusche sind ausgeblendet. der Preis dafür ist ein weiteres elektronisches Gerät das aufgeladen werden möchte. Zum Glück wieder über ein USB Kabel und ich muss daher kein weiteres Ladegerät mitnehmen

 

Nach mehr als 5 Jahren auf Achse habe ich einiges an Erfahrung gesammelt. Evtl sollte ich zu diesem Thema einmal eine Konferenzsession anbieten Zwinkerndes Smiley Es muss ja nicht immer SharePoint sein. Meine nächste Gelegenheit ist bei der  SharePoint konferenz in Wien.

Eure Meinung, soll ich das als Thema anbieten?

ppedv Team Blog: Eingabe Validierung mit HTML 5 und ASP.NET Webforms

Nachdem schon Windows 8 Apps bzw die WinRT API keine vernünftige Möglichkeit der Validierung von Benutzereingaben aufweist, hoffe ich im hochgelobten HTML5 Standard fündig zu werden. Dieser Artikel zeigt die Probleme von Validierung, die Möglichkeiten von HTML5 und die Umsetzung mit Webforms.

Never trust the User

Kennt man - alles und jedes muss überprüft werden, weil der wirkliche Feind in Layer 8 wartet. Soweit der zynische Teil. Eine Anwendung, egal ob Web oder Windows muss dem Benutzer unterstützen auch im Sinne korrekter Eingaben.

Erste Wahl sind vorbelegte Textboxen mit nützlichen Tipps. Üblicherweise Placeholder genannt und Standard in allen modernen Browser.

   1:<asp:TextBox ID="TextBox1" runat="server" placeholder="runde ins eckige"></asp:TextBox>

 

image

Als  nächstes kann man auf Input Typen beschränken, eine eMail Adresse, einen Zahlenbereich. Auch hier hat HTML5 ein neues Attribut Type das rund 10 verschiedene Typen vorsieht. ASP.NET Textbox setzt das als Textmode um.

image

Das Ergebnis ist ein Slider, der in jedem Browser anders aussieht, hier der Internet Explorer.

image

Noch schwieriger wird es mit dem Typ date, der von vielen Browsern, vor allem den mobilen, überhaupt nicht unterstützt wird. In Chrome erhält der Benutzer ein Kalender Popup.

Das ist ein Fehler

Man kennt das von der Schule. Der Lehrer gibt die korrigierte Schulaufgabe zurück. Blau geschrieben wimmelt es nur so von roten Farbklecksen. Mal durchgestrichen, mal unterstrichen, korrekter Text darüber geschrieben, ganz üble Sachen rechts erläutert. Was  leider nicht geht, ist ein nochmaliges Form Submit.

In der IT ist es nicht viel anders. Fehlermeldungen tauchen überall auf. Bekannt und beliebt ist die Blase (Bubble). Das HTML5 Attribut required (egal ob mit oder ohne Wert) wirkt entsprechend, wenn der Benutzer den Cursor in das rot umrandete Eingabefeld setzt.

 

   1:<asp:TextBox ID="TextBox5" runat="server" required ></asp:TextBox>

image

Die Eingaberegel wird so hart codiert in das User Interface Design. Damit werden eine Reihe neuer Probleme aufgeworfen.

HTML5 wäre nicht komplett, wenn es nicht auch eine CSS Variante gibt.  Damit lassen sich korrekt gefüllte Textboxen inline markieren.

   1:  input:required:valid {
   2:                  background-image: url(valid.png);
   3:                  background-position: right center;
   4:                  background-repeat: no-repeat;
   5:              }
   6:   
   7:              input:required:invalid {
   8:                  background-image: url(invalid.png);
   9:                  background-position: right center;
  10:                  background-repeat: no-repeat;
  11:                  
  12:              }
  13:   
  14:              input[type="text"] {
  15:                  font: 14px Consolas,"Courier New",serif;
  16:              }
image

Um das das X aus dem Input zu entfernen, gibt es einen CSS Hack.

   1:  ::-ms-clear {
   2:     display: none;
   3:  }

 

Wohin das alles

Um alle möglichen Geräte und Ihre Browser zu erreichen, kann man leider nicht jede Funktion aus HTML5 wie Attribut, Javascript Logik oder CSS verwenden. Dazu kommt das Problem der Darstellung, die Useability. Touchgeräte, kleine Screens dicke Finger.

Also endet man in vielen Eingabeformularen mit einfachen roten Text unterhalb des Eingabe Feldes, der dynamisch eingefügt wird.
Das lässt sich mit ASP.NET Webforms Steuerelement durchaus einfach und intutiv lösen

   1:  <html>
   2:  <head runat="server">
   3:      <style>
   4:          fieldset ol li {
   5:              padding-bottom: 5px;
   6:              list-style-type: none;
   7:          }
   8:   
   9:          label {
  10:              display: block;
  11:              font-size: 1.2em;
  12:              font-weight: 600;
  13:          }
  14:          .fehler
  15:          {
  16:                display: block;
  17:              font-size: 1em;
  18:              color:red;
  19:          }
  20:      </style>
  21:  </head>
  22:  <body>
  23:      <form id="form1" runat="server">
  24:          <fieldset>
  25:              <legend>mein Formular</legend>
  26:              <ol>
  27:                  <li>
  28:                      <asp:Label ID="Label1" runat="server" 
Text="name" AssociatedControlID="TextBox1"></asp:Label>
  29:                      <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
  30:                      <asp:RequiredFieldValidator ID="RequiredFieldValidator1" 
runat="server" ControlToValidate="TextBox1"
  31:                          ErrorMessage="bitte ausfüllen" 
CssClass="fehler"></asp:RequiredFieldValidator>
  32:                    </li>
  33:                  <li>
  34:                      <asp:Label ID="Label2" runat="server" Text="vorname" 
AssociatedControlID="TextBox2"></asp:Label>
  35:                      <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
  36:                      <asp:RequiredFieldValidator ID="RequiredFieldValidator2"
runat="server" ControlToValidate="TextBox2"
  37:                          ErrorMessage="bitte ausfüllen" 
CssClass="fehler"></asp:RequiredFieldValidator>
  38:                  </li>
  39:                  <li>
  40:                      <asp:Button ID="Button1" runat="server" Text="Button" />
  41:                  </li>
  42:              </ol>
  43:          </fieldset>
  44:      </form>
  45:  </body>
  46:  </html>



Im Internet Explorer ein funktionelles Ergebnis mit einwandfreien HTML5 Code der dann für Frameworks wie Bootstrap oder JQuery Mobile weiter verwendet werden kann um die UI auf zu hübschen.

image

Karsten Kempe: Heimspiel bei den Dodneddern

dnug_logoAm kommenden Donnerstag, 27.03.2014, bin ich bei der .Net UserGroup Franken zu Gast. Über dieses Heimspiel freue ich mich ganz besonders. Ich werde dort die Planungskomponenten des Team Foundation Server 2013 (TFS 2013) vorstellen. Los geht’s um 19.00Uhr in den Räumen der conplement AG – Südwestpark 92 in Nürnberg.

Hier eine kurze Zusammenfassung des Vortrags:

Planung ist das halbe Leben

Software-Entwicklung ist mehr als nur Code schreiben und diesen verwalten. Wenn man sich den Lebenszyklus einer Anwendung ansieht, dann wird man feststellen, dass an dessen erster Stelle die Idee (!) steckt und deren Beschreibung, aus der dann die Anforderungen an das Entwicklungsteam entstehen. Die Visualisierung dieser Anforderungen, Aufgaben und der Verfügbarkeit der Team-Mitglieder ist ein entscheidendes Erfolgskriterium, um Software erfolgreicher realisieren zu können. Jedes Team sollte jederzeit wissen, wie viel Arbeit noch zu leisten ist, um ein gemeinsames Ziel zu erreichen.

In diesem Vortrag lernen Sie den Team Foundation Server 2013 und dessen Planungstools kennen. Erfahren Sie, wie Sie Anforderungen, Bugs und Aufgaben im Team Foundation Server anlegen und pflegen und wie Sie einen Überblick über Ihre Teamziele behalten.

ppedv Team Blog: SQL Server 2014 – RTM –1. April Release Datum

SQL Server 2014 ist fertig! Am 1. April wird SQL Server zum Download zur Verfügung gestellt werden.   Quentin Clark, corporate vice president der  Data Platform Group verkündete heute im offiziellen SQL Server Blog  den Erscheinungstermin. (-> http://blogs.technet.com/b/dataplatforminsider/archive/2014/03/18/sql-server-2014-releases-april-1.aspx)

Schon einige male wurde der 1.April als Erscheinungstermin übergangen (siehe  bspw, Sharepoint Designer) um ja nicht als April Scherz  zu gelten. Dies dürfte auf den SQL Server 2014 nicht zutreffen. Wenn ein Server der letzten Jahre großes Lob verdient hat, dann dieser: inMemory Tabellen, Native kompilierte Prozeduren, Performancegewinn um über das 10 fache bei gleicher Hardware, updatebarer Columnstore Index bei extremer Kompressionsrate, erweiterte AlwaysOn Availabilitygroups und und und..  Das ist kein R2, das ist kein besseres SP. Das ist eine neue Generation!

Wer also keine Sekunden verpassen möchte, der kann sie hier registrieren, um per Email benachrichtigt zu werden.

Möchtest du mehr zu SQL wissen, dann schau mal hier: http://www.ppedv.de/SQL

friends header

bloggers headline

links header

 
Don't contact us via this (fleischfalle@alphasierrapapa.com) email address.