Freigeben über


Anhang: Die Fix It-Beispielanwendung (Erstellen Real-World Cloud-Apps mit Azure)

von Rick Anderson, Tom Dykstra

Herunterladen des Projekts "Fix It"

Das E-Book Building Real World Cloud Apps with Azure basiert auf einer Präsentation, die von Scott Guthrie entwickelt wurde. Es werden 13 Muster und Methoden erläutert, die Ihnen helfen können, Web-Apps für die Cloud erfolgreich zu entwickeln. Informationen zum E-Book finden Sie im ersten Kapitel.

Dieser Anhang zum E-Book Erstellen von Cloud-Apps mit Azure enthält die folgenden Abschnitte, die zusätzliche Informationen zur Fix It-Beispielanwendung enthalten, die Sie herunterladen können:

Bekannte Probleme

Die Fix It-App wurde ursprünglich entwickelt, um einige der in diesem E-Book dargestellten Muster so einfach wie möglich zu veranschaulichen. Da es sich bei dem E-Book jedoch um das Erstellen realer Apps handelt, haben wir den Fix It-Code einem Überprüfungs- und Testprozess unterzogen, der dem entspricht, was wir für veröffentlichte Software tun würden. Wir haben eine Reihe von Problemen gefunden, und wie bei jeder realen Anwendung wurden einige von ihnen behoben, und einige davon haben wir auf ein späteres Release verschoben.

Die folgende Liste enthält Probleme, die in einer Produktionsanwendung behoben werden sollten, aber aus dem einen oder anderen Grund haben wir uns entschieden, in der ersten Version der Beispielanwendung "Fix It" nicht anzugehen.

Sicherheit

  • Stellen Sie sicher, dass Sie keine Aufgabe einem nicht vorhandenen Besitzer zuweisen können.
  • Stellen Sie sicher, dass Sie nur Aufgaben anzeigen und ändern können, die Sie erstellt haben oder denen Sie zugewiesen sind.
  • Verwenden Sie HTTPS für Anmeldeseiten und Authentifizierungscookies.
  • Geben Sie ein Zeitlimit für Authentifizierungscookies an.

Eingabeüberprüfung

Im Allgemeinen würde eine Produktions-App mehr Eingabeüberprüfungen durchführen als die Fix It-App. Beispielsweise sollte die für den Upload zulässige Bildgröße/Bilddateigröße begrenzt sein.

Administratorfunktionen

Ein Administrator sollte in der Lage sein, den Besitz für vorhandene Aufgaben zu ändern. Beispielsweise kann der Ersteller einer Aufgabe das Unternehmen verlassen, sodass niemand die Berechtigung zum Verwalten der Aufgabe hat, es sei denn, der Administratorzugriff ist aktiviert.

Verarbeitung von Warteschlangennachrichten

Die Verarbeitung von Warteschlangennachrichten in der Fix It-App wurde so konzipiert, dass sie einfach ist, um das warteschlangenorientierte Arbeitsmuster mit einer minimalen Menge an Code zu veranschaulichen. Dieser einfache Code wäre für eine tatsächliche Produktionsanwendung nicht ausreichend.

  • Der Code garantiert nicht, dass jede Warteschlangennachricht höchstens einmal verarbeitet wird. Wenn Sie eine Nachricht aus der Warteschlange erhalten, gibt es einen Timeoutzeitraum, in dem die Nachricht für andere Warteschlangenlistener unsichtbar ist. Wenn das Timeout abläuft, bevor die Nachricht gelöscht wird, wird die Nachricht wieder sichtbar. Wenn eine Workerrolle instance eine Nachricht daher lange mit der Verarbeitung einer Nachricht verbringt, ist es theoretisch möglich, dass dieselbe Nachricht zweimal verarbeitet wird, was zu einer doppelten Aufgabe in der Datenbank führt. Weitere Informationen zu diesem Problem finden Sie unter Verwenden von Azure Storage-Warteschlangen.
  • Die Warteschlangenabfragelogik kann durch batchbasierte Nachrichtenabrufe kostengünstiger sein. Jedes Mal, wenn Sie CloudQueue.GetMessageAsync aufrufen, fallen Transaktionskosten an. Stattdessen können Sie CloudQueue.GetMessagesAsync aufrufen (beachten Sie den Plural "s"), wodurch mehrere Nachrichten in einer einzelnen Transaktion abgerufen werden. Die Transaktionskosten für Azure Storage-Warteschlangen sind sehr niedrig, sodass die Auswirkungen auf die Kosten in den meisten Szenarien nicht erheblich sind.
  • Die enge Schleife im Code für die Nachrichtenverarbeitung der Warteschlange verursacht CPU-Affinität, die nicht effizient mehrere Kern-VMs nutzt. Ein besserer Entwurf würde Taskparallelität verwenden, um mehrere asynchrone Aufgaben parallel auszuführen.
  • Die Verarbeitung von Warteschlangennachrichten weist nur rudimentäre Ausnahmebehandlung auf. Beispielsweise verarbeitet der Code keine vergifteten Nachrichten. (Wenn die Nachrichtenverarbeitung eine Ausnahme verursacht, müssen Sie den Fehler protokollieren und die Nachricht löschen, oder die Workerrolle versucht, sie erneut zu verarbeiten, und die Schleife wird auf unbestimmte Zeit fortgesetzt.)

SQL-Abfragen sind ungebunden

Mit dem aktuellen Fix It-Code wird keine Einschränkung festgelegt, wie viele Zeilen die Abfragen für Indexseiten zurückgeben können. Wenn eine große Menge von Aufgaben in die Datenbank eingegeben wird, kann die Größe der resultierenden Listen zu Leistungsproblemen führen. Die Lösung besteht darin, paging zu implementieren. Ein Beispiel finden Sie unter Sortieren, Filtern und Paging mit dem Entity Framework in einer ASP.NET MVC-Anwendung.

Die Fix It-App verwendet die FixItTask-Entitätsklasse, um Informationen zwischen dem Controller und der Ansicht zu übergeben. Eine bewährte Methode besteht darin, Ansichtsmodelle zu verwenden. Das Domänenmodell (z. B. die FixItTask-Entitätsklasse) ist auf das ausgelegt, was für die Datenpersistenz benötigt wird, während ein Ansichtsmodell für die Datenpräsentation entworfen werden kann.

Die Fix It-App speichert hochgeladene Bilder als öffentlich, was bedeutet, dass jeder, der die URL findet, auf die Bilder zugreifen kann. Die Bilder könnten geschützt werden, anstatt öffentlich zu sein.

Keine PowerShell-Automatisierungsskripts für Warteschlangen

PowerShell-Beispielautomatisierungsskripts wurden nur für die Basisversion von Fix It geschrieben, die vollständig in Azure App Service Web-Apps ausgeführt wird. Wir haben keine Skripts zum Einrichten und Bereitstellen in der Web-App und cloud Service-Umgebung bereitgestellt, die für die Warteschlangenverarbeitung erforderlich sind.

Spezielle Behandlung von HTML-Codes in der Benutzereingabe

ASP.NET verhindert automatisch viele Möglichkeiten, wie böswillige Benutzer angriffe auf websiteübergreifende Skripterstellung versuchen können, indem sie Skript in Benutzereingabetextfelder eingeben. Und das MVC-Hilfsprogramm DisplayFor , das zum Anzeigen von Aufgabentiteln und Notizen verwendet wird, codiert automatisch HTML-codierte Werte, die an den Browser gesendet werden. In einer Produktions-App sollten Sie jedoch zusätzliche Maßnahmen ergreifen. Weitere Informationen finden Sie unter Anforderungsüberprüfung in ASP.NET.

Bewährte Methoden

Im Folgenden finden Sie einige Probleme, die behoben wurden, nachdem sie in der Codeüberprüfung und dem Testen der ursprünglichen Version der Fix It-App erkannt wurden. Einige wurden dadurch verursacht, dass der ursprüngliche Coder nicht über eine bestimmte bewährte Methode wusste, andere einfach, weil der Code schnell geschrieben wurde und nicht für freigegebene Software vorgesehen war. Wir listen die Probleme hier auf, falls wir etwas aus dieser Überprüfung und Tests gelernt haben, das für andere, die auch Web-Apps entwickeln, hilfreich sein könnte.

Entsorgen des Datenbankrepositorys

Die FixItTaskRepository Klasse muss das Entity Framework DbContext instance. Dies haben wir in der FixItTaskRepository Klasse implementiertIDisposable:

public class FixItTaskRepository : IFixItTaskRepository, IDisposable
{
    private MyFixItContext db = new MyFixItContext();

    // other code not shown

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // Free managed resources.
            if (db != null)
            {
                db.Dispose();
                db = null;
            }
        }
    }
}

Beachten Sie, dass AutoFac die FixItTaskRepository instance automatisch entsorgt, sodass sie nicht explizit entsorgt werden muss.

Eine weitere Option besteht darin, die DbContext Membervariable aus FixItTaskRepositoryzu entfernen und stattdessen eine lokale DbContext Variable innerhalb jeder Repositorymethode innerhalb einer using Anweisung zu erstellen. Beispiel:

// Alternate way to dispose the DbContext
using (var db = new MyFixItContext())
{
    fixItTask = await db.FixItTasks.FindAsync(id);
}

Registrieren von Singletons als solche bei DI

Da nur eine instance der PhotoService Klasse und Logger Klasse benötigt wird, sollten diese Klassen als einzelinstanzen für die Abhängigkeitsinjektion in DependenciesConfig.cs registriert werden:

builder.RegisterType<Logger>().As<ILogger>().SingleInstance();
builder.RegisterType<FixItTaskRepository>().As<IFixItTaskRepository>();
builder.RegisterType<PhotoService>().As<IPhotoService>().SingleInstance();

Sicherheit: Anzeigen von Fehlerdetails für Benutzer

Die ursprüngliche Fix It-App verfügte nicht über eine generische Fehlerseite und ließ einfach alle Ausnahmen auf die Benutzeroberfläche blasen, sodass einige Ausnahmen wie Datenbankverbindungsfehler dazu führen können, dass eine vollständige Stapelablaufverfolgung im Browser angezeigt wird. Detaillierte Fehlerinformationen können manchmal Angriffe böswilliger Benutzer erleichtern. Die Lösung besteht darin, die Ausnahmedetails zu protokollieren und dem Benutzer eine Fehlerseite anzuzeigen, die keine Fehlerdetails enthält. Die Fix It-App wurde bereits protokolliert, und um eine Fehlerseite anzuzeigen, haben wir in der Web.config-Datei hinzugefügt <customErrors mode=On> .

<system.web>
  <customErrors mode="On"/>
  <authentication mode="None" />
  <compilation debug="true" targetFramework="4.5" />
  <httpRuntime targetFramework="4.5" />
</system.web>

Dies führt standardmäßig dazu , dass Views\Shared\Error.cshtml auf Fehler angezeigt wird. Sie können Error.cshtml anpassen oder eine eigene Fehlerseitenansicht erstellen und ein defaultRedirect Attribut hinzufügen. Sie können auch verschiedene Fehlerseiten für bestimmte Fehler angeben.

Sicherheit: Nur zulassen, dass eine Aufgabe vom Ersteller bearbeitet wird

Auf der Seite Dashboardindex werden nur Aufgaben angezeigt, die vom angemeldeten Benutzer erstellt wurden, aber ein böswilliger Benutzer könnte eine URL mit einer ID für die Aufgabe eines anderen Benutzers erstellen. In DashboardController.cs wurde Code hinzugefügt, um in diesem Fall eine 404 zurückzugeben:

public async Task<ActionResult> Edit(int id)
{
    FixItTask fixittask = await fixItRepository.FindTaskByIdAsync(id);
    if (fixittask == null)
    {
        return HttpNotFound();
    }

    // Verify logged in user owns this FixIt task.
    if (User.Identity.Name != fixittask.Owner)
    {
       return HttpNotFound();
    }

    return View(fixittask);
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(int id, [Bind(Include = "CreatedBy,Owner,Title,Notes,PhotoUrl,IsDone")]FormCollection form)
{
    FixItTask fixittask = await fixItRepository.FindTaskByIdAsync(id);

    // Verify logged in user owns this FixIt task.
    if (User.Identity.Name != fixittask.Owner)
    {
       return HttpNotFound();
    }

    if (TryUpdateModel(fixittask, form))
    {
        await fixItRepository.UpdateAsync(fixittask);
        return RedirectToAction("Index");
    }

    return View(fixittask);
}

Ausnahmen nicht schlucken

Die ursprüngliche Fix It-App hat gerade NULL zurückgegeben, nachdem eine Ausnahme protokolliert wurde, die aus einer SQL-Abfrage resultierte:

catch (Exception e)
{
    log.Error(e, "Error in FixItTaskRepository.FindTasksByOwnerAsync(userName={0})", userName);
    return null;
}

Dadurch sieht es für den Benutzer so aus, als ob die Abfrage erfolgreich war, aber einfach keine Zeilen zurückgibt. Die Lösung besteht darin, die Ausnahme nach dem Erfassen und Protokollieren erneut auszulösen:

catch (Exception e)
{
    log.Error(e, "Error in FixItTaskRepository.FindTasksByCreatorAsync(creater={0})", creator);
    throw;
}

Erfassen aller Ausnahmen in Workerrollen

Alle nicht behandelten Ausnahmen in einer Workerrolle führen dazu, dass die VM wiederverwendet wird, sodass Sie alles, was Sie tun, in einen Try-Catch-Block umschließen und alle Ausnahmen behandeln möchten.

Angeben der Länge für Zeichenfolgeneigenschaften in Entitätsklassen

Um einfachen Code anzuzeigen, gab die ursprüngliche Version der Fix It-App keine Längen für die Felder der FixItTask-Entität an, und daher wurden sie in der Datenbank als varchar(max) definiert. Daher würde die Benutzeroberfläche fast jede Menge an Eingaben akzeptieren. Die Angabe von Längen legt Grenzwerte fest, die sowohl für Benutzereingaben in der Webseite als auch für die Spaltengröße in der Datenbank gelten:

public class FixItTask
{
    public int FixItTaskId  { get; set; }
    [StringLength(80)]
    public string CreatedBy { get; set; }
    [Required]
    [StringLength(80)]
    public string Owner { get; set; }
    [Required]
    [StringLength(80)]
    public string Title { get; set; }
    [StringLength(1000)]
    public string Notes { get; set; }
    [StringLength(200)]
    public string PhotoUrl { get; set; }
    public bool IsDone      { get; set; }  
}

Markieren sie private Mitglieder als schreibgeschützte Elemente, wenn keine Änderung erwartet wird.

Beispielsweise wird in der DashboardController -Klasse eine instance von FixItTaskRepository erstellt, die sich nicht ändern soll. Daher haben wir sie als schreibgeschützter Wert definiert.

public class DashboardController : Controller
    {
        private readonly IFixItTaskRepository fixItRepository = null;

Liste verwenden. Any() anstelle von list. Count() > 0

Wenn Sie sich nur darum kümmern, ob ein oder mehrere Elemente in einer Liste den angegebenen Kriterien entsprechen, verwenden Sie die Any-Methode , da sie zurückgibt, sobald ein Element gefunden wird, das den Kriterien entspricht, während die Count Methode immer jedes Element durchlaufen muss. Die Datei "Dashboard Index.cshtml " enthielt ursprünglich folgenden Code:

@if (Model.Count() == 0) {
    <br />
    <div>You don't have anything currently assigned to you!!!</div>
}

Wir haben es in folgendes geändert:

@if (!Model.Any()) {
    <br />
    <div>You don't have anything currently assigned to you!!!</div>
}

Generieren von URLs in MVC-Ansichten mithilfe von MVC-Hilfsprogrammen

Für die Schaltfläche Fix It erstellen auf der Startseite hat die Fix It-App ein Ankerelement hartcodiert:

<a href="/Tasks/Create" class="btn btn-primary btn-large">Create a New FixIt &raquo;</a>

Für Solche Ansichts-/Aktionslinks ist es besser, das HTML-Hilfsprogramm Url.Action zu verwenden, z. B.:

@Url.Action("Create","Tasks")

Verwenden von Task.Delay anstelle von Thread.Sleep in der Workerrolle

Die New-Project-Vorlage fügt Thread.Sleep den Beispielcode für eine Workerrolle ein, aber wenn der Thread in den Ruhezustand versetzt wird, kann dies dazu führen, dass der Threadpool zusätzliche unnötige Threads erzeugt. Sie können dies vermeiden, indem Sie stattdessen Task.Delay verwenden.

while (true)
{
    try
    {
        await queueManager.ProcessMessagesAsync();
    }
    catch (Exception ex)
    {
        logger.Error(ex, "Exception in worker role Run loop.");
    }
    await Task.Delay(1000);
}

Async void vermeiden

Wenn eine asynchrone Methode keinen Wert zurückgeben muss, geben Sie anstelle voidvon einen Typ zurückTask.

Dieses Beispiel stammt aus der FixItQueueManager -Klasse:

// Correct
public async Task SendMessageAsync(FixItTask fixIt) { ... }

// Incorrect
public async void SendMessageAsync(FixItTask fixIt) { ... }

Sie sollten nur für Ereignishandler der obersten Ebene verwenden async void . Wenn Sie eine Methode als async voiddefinieren, kann der Aufrufer nicht auf die -Methode warten oder Ausnahmen abfangen, die von der Methode ausgelöst werden. Weitere Informationen finden Sie unter Bewährte Methoden in der asynchronen Programmierung.

Verwenden eines Abbruchtokens zum Unterbrechen der Workerrollenschleife

In der Regel enthält die Run-Methode für eine Workerrolle eine Endlosschleife. Wenn die Workerrolle beendet wird, wird die RoleEntryPoint.OnStop-Methode aufgerufen. Sie sollten diese Methode verwenden, um die Arbeit, die innerhalb der Run-Methode ausgeführt wird, abzubrechen und ordnungsgemäß zu beenden. Andernfalls wird der Prozess möglicherweise in der Mitte eines Vorgangs beendet.

Deaktivieren der automatischen MIME-Sniffing-Prozedur

In einigen Fällen meldet internet Explorer einen MIME-Typ, der sich von dem vom Webserver angegebenen Typ unterscheidet. Wenn für instance internet Explorer HTML-Inhalt in einer Datei findet, die mit dem HTTP-Antwortheader Content-Type: text/plain bereitgestellt wird, bestimmt Internet Explorer, dass der Inhalt als HTML gerendert werden soll. Leider kann dieses "MIME-Sniffing" auch zu Sicherheitsproblemen für Server führen, die nicht vertrauenswürdige Inhalte hosten. Um dieses Problem zu bekämpfen, hat internet Explorer 8 eine Reihe von Änderungen am MIME-Typ-Bestimmungscode vorgenommen und ermöglicht es Anwendungsentwicklern, die MIME-Sniffing zu deaktivieren. Der folgende Code wurde der Web.config-Datei hinzugefügt.

<system.webServer>
     <httpProtocol>
        <customHeaders>
           <add name="X-Content-Type-Options" value="nosniff"/>
        </customHeaders>
     </httpProtocol>
     <modules>
      <remove name="FormsAuthenticationModule" />
    </modules>
  </system.webServer>

Aktivieren der Bündelung und Minimierung

Wenn Visual Studio ein neues Webprojekt erstellt, ist die Bündelung und Minimierung von JavaScript-Dateien standardmäßig nicht aktiviert. Wir haben eine Codezeile in BundleConfig.cs hinzugefügt:

// For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862
public static void RegisterBundles(BundleCollection bundles)
{
    bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                "~/Scripts/jquery-{version}.js"));
 
   // Code removed for brevity/
 
   BundleTable.EnableOptimizations = true;
}

Festlegen eines Ablaufzeitlimits für Authentifizierungscookies

Standardmäßig laufen Authentifizierungscookies in zwei Wochen ab. Eine kürzere Zeit ist sicherer. Sie können diese Einstellung in StartupAuth.cs ändern:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login"),
    ExpireTimeSpan = System.TimeSpan.FromMinutes(20)
});

Ausführen der App in Visual Studio auf ihrem lokalen Computer

Es gibt zwei Möglichkeiten, die Fix It-App auszuführen:

  • Führen Sie die Basisanwendung aus, die neue Aufgaben direkt in die SQL-Datenbank schreibt.
  • Führen Sie die Anwendung mit einer Warteschlange und einem Back-End-Dienst aus, um Aufgaben zu erstellen. Das Warteschlangenmuster wird im Kapitel Warteschlangenzentriertes Arbeitsmuster beschrieben.

Ausführen der Basisanwendung

  1. Installieren Sie Visual Studio 2017.
  2. Installieren Sie das Azure SDK für .NET für Visual Studio.
  3. Laden Sie die .zip-Datei aus der MSDN Code Gallery herunter.
  4. Klicken Sie in Explorer mit der rechten Maustaste auf die .zip Datei, klicken Sie auf Eigenschaften, und klicken Sie dann im Eigenschaftenfenster auf Blockierung aufheben.
  5. Entzippen Sie die Datei.
  6. Doppelklicken Sie auf die SLN-Datei, um Visual Studio zu starten.
  7. Klicken Sie im Menü Extras auf NuGet-Paket-Manager und dann auf Paket-Manager-Konsole.
  8. Klicken Sie in der Paket-Manager-Konsole (PMC) auf Wiederherstellen.
  9. Beenden Sie Visual Studio.
  10. Starten Sie den Azure Storage-Emulator.
  11. Starten Sie Visual Studio neu, und öffnen Sie die Projektmappendatei, die Sie im vorherigen Schritt geschlossen haben.
  12. Stellen Sie sicher, dass das Projekt FixIt als Startprojekt festgelegt ist, und drücken Sie dann STRG+F5, um das Projekt auszuführen.

Ausführen der Anwendung mit Warteschlangenverarbeitung

  1. Befolgen Sie die Anweisungen unter Ausführen der Basisanwendung, und schließen Sie dann den Browser, und schließen Sie Visual Studio.

  2. Starten Sie Visual Studio mit Administratorrechten. (Sie verwenden den Azure-Computeemulator, für den Administratorrechte erforderlich sind.)

  3. Ändern Sie in der Anwendung Web.config Datei im Projekt MyFixIt (dem Webprojekt) den Wert von appSettings/UseQueues in "true":

    <appSettings>
        <!-- Other settings not shown -->
        <add key="UseQueues" value="true"/>
    </appSettings>
    
  4. Wenn der Azure Storage-Emulator noch nicht ausgeführt wird, starten Sie ihn erneut.

  5. Führen Sie das Webprojekt FixIt und das Projekt MyFixItCloudService gleichzeitig aus.

    Verwenden von Visual Studio:

    1. Drücken Sie F5 , um das Projekt FixIt auszuführen.
    2. Klicken Sie in Projektmappen-Explorer mit der rechten Maustaste auf das Projekt MyFixItCloudService, und klicken Sie dann auf Debuggen>Neue Instanz starten.

    Verwenden von Visual Studio 2013 Express for Web:

    1. Klicken Sie in Projektmappen-Explorer mit der rechten Maustaste auf die Lösung FixIt, und wählen Sie Eigenschaften aus.

    2. Wählen Sie Mehrere Startprojekte aus.

    3. Wählen Sie in der Dropdownliste Aktion unter MyFixIt und MyFixItCloudService die Option Start aus.

    4. Klicken Sie auf OK.

    5. Drücken Sie F5, um beide Projekte auszuführen.

      Wenn Sie das Projekt MyFixItCloudService ausführen, startet Visual Studio den Azure-Computeemulator. Je nach Firewallkonfiguration müssen Sie möglicherweise den Emulator über die Firewall zulassen.

Bereitstellen der Basis-App für Azure App Service Web-Apps mithilfe der Windows PowerShell-Skripts

Um das Muster "Alles automatisieren " zu veranschaulichen, wird die Fix It-App mit Skripts bereitgestellt, die eine Umgebung in Azure einrichten und das Projekt in der neuen Umgebung bereitstellen. In den folgenden Anweisungen wird erläutert, wie Sie die Skripts verwenden.

Wenn Sie in Azure ohne Verwendung von Warteschlangen ausführen möchten und die Änderungen für die lokale Ausführung mit Warteschlangen vorgenommen haben, stellen Sie sicher, dass Sie den Wert useQueues appSetting wieder auf false festlegen, bevor Sie mit den folgenden Anweisungen fortfahren.

Bei diesen Anweisungen wird davon ausgegangen, dass Sie die Lösung "Fix It" bereits heruntergeladen und lokal ausgeführt haben und dass Sie über ein Azure-Konto oder ein Azure-Abonnement verfügen, für das Sie autorisiert sind.

  1. Installieren Sie die Azure PowerShell-Konsole. Anweisungen hierzu finden Sie unter Installieren und Konfigurieren von Azure PowerShell.

    Diese angepasste Konsole ist für die Arbeit mit Ihrem Azure-Abonnement konfiguriert. Das Azure-Modul wird im Verzeichnis Programme installiert und bei jeder Verwendung der Azure PowerShell-Konsole automatisch importiert.

    Wenn Sie lieber mit einem anderen Hostprogramm arbeiten möchten, z. B. Windows PowerShell ISE, müssen Sie das Import-Module-Cmdlet zum Importieren des Azure-Moduls oder einen Befehl im Azure-Modul verwenden, um den automatischen Import des Moduls auszulösen.

  2. Starten Sie Azure PowerShell mit der Option Als Administrator ausführen.

  3. Führen Sie das Cmdlet Set-ExecutionPolicy aus, um die Azure PowerShell Ausführungsrichtlinie auf festzulegenRemoteSigned. Geben Sie Y (für Ja) ein, um die Richtlinienänderung abzuschließen.

    PS C:\> Set-ExecutionPolicy RemoteSigned
    

    Mit dieser Einstellung können Sie lokale Skripts ausführen, die nicht digital signiert sind. (Sie können die Ausführungsrichtlinie auch auf Unrestrictedfestlegen, wodurch der Entsperrungsschritt später überflüssig wäre, dies wird jedoch aus Sicherheitsgründen nicht empfohlen.)

  4. Führen Sie das Add-AzureAccount Cmdlet aus, um PowerShell mit Anmeldeinformationen für Ihr Konto einzurichten.

    PS C:\> Add-AzureAccount
    

    Diese Anmeldeinformationen laufen nach einer bestimmten Zeit ab, und Sie müssen das Add-AzureAccount Cmdlet erneut ausführen. Da dieses E-Book geschrieben wird, beträgt das Zeitlimit vor Ablauf der Anmeldeinformationen 12 Stunden.

  5. Wenn Sie über mehrere Abonnements verfügen, verwenden Sie das Cmdlet Select-AzureSubscription, um das Abonnement anzugeben, in dem Sie die Testumgebung erstellen möchten.

  6. Importieren Sie mithilfe der Cmdlets und Import-AzurePublishSettingsFile ein Verwaltungszertifikat für dasselbe Get-AzurePublishSettingsFile Azure-Abonnement. Das erste dieser Cmdlets lädt eine Zertifikatdatei herunter, und im zweiten geben Sie den Speicherort dieser Datei an, um sie zu importieren. > [! WICHTIG]

    Bewahren Sie die heruntergeladene Datei an einem sicheren Speicherort auf, oder löschen Sie sie, wenn Sie damit fertig sind, da sie ein Zertifikat enthält, das zum Verwalten Ihrer Azure-Dienste verwendet werden kann.

    PS C:\Users\username\Documents\Visual Studio 2013\Projects\MyFixIt\Automation> Get-AzurePublishSettingsFile
    PS C:\Users\username\Documents\Visual Studio 2013\Projects\MyFixIt\Automation> Import-AzurePublishSettingsFile "C:\Users
    \username\Downloads\Azure MSDN - Visual Studio Ultimate-12-14-2013-credentials.publishsettings"
    

    Das Zertifikat wird für einen REST-API-Aufruf verwendet, der die IP-Adresse des Entwicklungscomputers erkennt, um eine Firewallregel auf dem SQL-Datenbank Server festzulegen.

  7. Führen Sie das Cmdlet Set-Location (Aliase sind cd, chdirund sl) aus, um zu dem Verzeichnis zu navigieren, das die Skripts enthält. (Sie befinden sich im Ordner Automation im Lösungsordner Fix It.) Fügen Sie den Pfad in Anführungszeichen ein, wenn einer der Verzeichnisnamen Leerzeichen enthält. Um beispielsweise zum Verzeichnis zu c:\Sample Apps\FixIt\Automation navigieren, können Sie den folgenden Befehl eingeben:

    PS C:\> cd "c:\Sample Apps\MyFixIt\Automation"
    
  8. Verwenden Sie das Cmdlet Unblock-File, damit Windows PowerShell diese Skripts ausführen können. (Die Skripts werden blockiert, da sie aus dem Internet heruntergeladen wurden.)

    Warnung

    Sicherheit: Öffnen Sie die Datei in Editor, überprüfen Sie die Befehle, und vergewissern Sie sich, dass sie keinen schädlichen Code enthalten, bevor Sie mit einem Skript oder einer ausführbaren Datei ausgeführt Unblock-File werden.

    Mit dem folgenden Befehl wird das Unblock-File Cmdlet beispielsweise für alle Skripts im aktuellen Verzeichnis ausgeführt.

    PS C:\Sample Apps\FixIt\Automation> Unblock-File -Path .\*.ps1
    
  9. Um die Web-App für die Basis (keine Warteschlangenverarbeitung) zu erstellen, führen Sie das Skript zur Umgebungserstellung aus.

    Der erforderliche Name Parameter gibt den Namen der Datenbank an und wird auch für das Speicherkonto verwendet, das das Skript erstellt. Der Name muss innerhalb der azurewebsites.net Domäne global eindeutig sein. Wenn Sie einen nicht eindeutigen Namen angeben, z. B. Fixit oder Test (oder sogar wie im Beispiel fixitdemo), schlägt das New-AzureWebsite Cmdlet mit einem internen Fehler fehl, der einen Konflikt meldet. Das Skript konvertiert den Namen in Kleinbuchstaben, um die Namensanforderungen für Web-Apps, Speicherkonten und Datenbanken zu erfüllen.

    Der erforderliche SqlDatabasePassword Parameter gibt das Kennwort für das Administratorkonto an, das für SQL-Datenbank erstellt wird. Fügen Sie keine XML-Sonderzeichen in das Kennwort ein (& <> ;). Dies ist eine Einschränkung der Schreibweise der Skripts, nicht eine Einschränkung von Azure.

    Wenn Sie beispielsweise eine Web-App mit dem Namen "fixitdemo" erstellen und ein SQL Server Administratorkennwort "Passw0rd1" verwenden möchten, können Sie den folgenden Befehl eingeben:

    PS C:\Sample Apps\FixIt\Automation> .\New-AzureWebsiteEnv.ps1 -Name 
    fixitdemo <required params here>
    

    Der Name muss in der azurewebsites.net Domäne eindeutig sein, und das Kennwort muss SQL-Datenbank Anforderungen an die Kennwortkomplexität erfüllen. (Das Beispiel Passw0rd1 erfüllt die Anforderungen.)

    Beachten Sie, dass der Befehl mit "." beginnt. Um böswillige Ausführung von Skripts zu verhindern, erfordert Windows PowerShell, dass Sie beim Ausführen eines Skripts den vollqualifizierten Pfad zur Skriptdatei angeben. Sie können einen Punkt verwenden, um das aktuelle Verzeichnis (".") anzugeben oder den vollqualifizierten Pfad anzugeben, z. B.:

    PS C:\Temp\FixIt\Automation> C:\Temp\FixIt\Automation\New-AzureWebsiteEnv.ps1 -Name fixitdemo -SqlDatabasePassword Pas$w0rd
    

    Weitere Informationen zum Skript finden Sie mithilfe des Cmdlets Get-Help .

    PS C:\Sample Apps\FixIt\Automation> Get-Help -Full .\New-AzureWebsiteEnv.ps1
    

    Sie können die DetailedParameter , Full, Parametersund Examples des Cmdlets Get-Help verwenden, um die zurückgegebene Hilfe zu filtern.

    Wenn das Skript fehlschlägt oder Fehler generiert, z. B. "New-AzureWebsite: Call Set-AzureSubscription and Select-AzureSubscription first", haben Sie die Konfiguration von Azure PowerShell möglicherweise nicht abgeschlossen.

    Nach Abschluss des Skripts können Sie das Azure-Verwaltungsportal verwenden, um die erstellten Ressourcen anzuzeigen, wie im Kapitel Automatisieren von Alles gezeigt.

  10. Verwenden Sie das SkriptAzureWebsite.ps1 , um das FixIt-Projekt in der neuen Azure-Umgebung bereitzustellen. Beispiel:

    PS C:\Sample Apps\FixIt\Automation> .\Publish-AzureWebsite.ps1 ..\MyFixIt\MyFixIt.csproj -Launch
    

    Wenn die Bereitstellung abgeschlossen ist, wird der Browser mit "Fix It" in Azure geöffnet.

Problembehandlung bei Windows PowerShell Skripts

Die häufigsten Fehler, die beim Ausführen dieser Skripts auftreten, beziehen sich auf Berechtigungen. Stellen Sie sicher, dass Add-AzureAccount und Import-AzurePublishSettingsFile erfolgreich waren und dass Sie sie für dasselbe Azure-Abonnement verwendet haben. Auch wenn Add-AzureAccount dies erfolgreich war, müssen Sie es möglicherweise erneut ausführen. Die von hinzugefügten Add-AzureAccount Berechtigungen laufen in 12 Stunden ab.

Objektverweis nicht auf eine Instanz eines Objekts festgelegt.

Wenn das Skript Fehler wie "Objektverweis nicht auf eine instance eines Objekts festgelegt" zurückgibt, was bedeutet, dass Windows PowerShell kein zu verarbeitende Objekt finden können (dies ist eine NULL-Verweis-Ausnahme), führen Sie das Add-AzureAccount Cmdlet aus, und versuchen Sie es erneut.

New-AzureSqlDatabaseServer : Object reference not set to an instance of an object.
At C:\ps-test\azure-powershell-samples-master\WebSite\create-azure-sql.ps1:80 char:19
+ $databaseServer = New-AzureSqlDatabaseServer -AdministratorLogin $UserName -Admi ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [New-AzureSqlDatabaseServer], NullReferenceException
    + FullyQualifiedErrorId : 
Microsoft.WindowsAzure.Commands.SqlDatabase.Server.Cmdlet.NewAzureSqlDatabaseServer

InternalError: Beim Server ist ein interner Fehler aufgetreten.

Das New-AzureWebsite Cmdlet gibt einen internen Fehler zurück, wenn der Name in der azurewebsites.net Domäne nicht eindeutig ist. Um den Fehler zu beheben, verwenden Sie einen anderen Wert für den Namen, der sich im Parameter Name von New-AzureWebsiteEnv.ps1befindet.

New-AzureWebsite : InternalError: The server encountered an internal error. 
Please retry the request.
At line:1 char:1
+ New-AzureWebsite -Name fixitdemo
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          
: CloseError: (:) [New-AzureWebsite], Exception
+ FullyQualifiedErrorId : 
Microsoft.WindowsAzure.Commands.Websites.NewAzureWebsiteCommand

Neustarten des Skripts

Wenn Sie das New-AzureWebsiteEnv.ps1 Skript neu starten müssen, weil ein Fehler aufgetreten ist, bevor die Meldung "Skript ist abgeschlossen" gedruckt wurde, sollten Sie ressourcen löschen, die das Skript erstellt hat, bevor es angehalten wurde. Wenn das Skript beispielsweise bereits die ContosoFixItDemo-Web-App erstellt hat und Sie das Skript erneut mit demselben Namen ausführen, schlägt das Skript fehl, da der Name verwendet wird.

Verwenden Sie die folgenden Cmdlets, um zu bestimmen, welche Ressourcen das Skript vor dem Beenden erstellt hat:

  • Get-AzureWebsite
  • Get-AzureSqlDatabaseServer
  • Get-AzureSqlDatabase: Um dieses Cmdlet auszuführen, leiten Sie den Datenbankservernamen an weiter:Get-AzureSqlDatabaseGet-AzureSqlDatabaseServer | Get-AzureSqlDatabase.

Verwenden Sie die folgenden Befehle, um diese Ressourcen zu löschen. Beachten Sie, dass Sie beim Löschen des Datenbankservers automatisch die dem Server zugeordneten Datenbanken löschen.

  • Get-AzureWebsite -Name <WebsiteName> | Remove-AzureWebsite
  • Get-AzureSqlDatabase -Name <DatabaseName> -ServerName <DatabaseServerName> | Remove-SqlAzureDatabase
  • Get-AzureSqlDatabaseServer | Remove-AzureSqlDatabaseServer

Bereitstellen der App mit Warteschlangenverarbeitung in Azure App Service Web-Apps und einem Azure Cloud Service

Um Warteschlangen zu aktivieren, nehmen Sie die folgende Änderung in der MyFixIt\Web.config-Datei vor. Ändern Sie unter appSettingsden Wert von UseQueues in "true":

<appSettings>
    <!-- Other settings not shown -->
    <add key="UseQueues" value="true"/>
</appSettings>

Stellen Sie dann die MVC-Anwendung wie weiter oben beschrieben in einer Web-App in Azure App Service bereit.

Erstellen Sie als Nächstes einen neuen Azure-Clouddienst. Die in der Fix It-App enthaltenen Skripts erstellen oder stellen den Clouddienst nicht bereit, daher müssen Sie hierfür Azure-Portal verwenden. Klicken Sie im Portal auf Neue -- ComputeCloudService-Schnellerstellung -- , und geben Sie dann eine URL und einen Rechenzentrumsstandort ein. Verwenden Sie dasselbe Rechenzentrum, in dem Sie die Web-App bereitgestellt haben.

Diagramm des Azure Cloud Service-Portals und der verschiedenen Registerkarten mit ihren verfügbaren Auswahlmöglichkeiten zum Erstellen eines neuen Azure-Clouddienstprojekts

Bevor Sie den Clouddienst bereitstellen können, müssen Sie einige Konfigurationsdateien aktualisieren.

Ersetzen Sie in MyFixIt.WorkerRole\app.config unter connectionStringsden Wert des appdb Verbindungszeichenfolge durch den tatsächlichen Verbindungszeichenfolge für die SQL-Datenbank. Sie können die Verbindungszeichenfolge über das Portal abrufen. Klicken Sie im Portal auf SQL-Datenbanken - appdb - SQL-Datenbank Verbindungszeichenfolgen für ADO .Net, ODBC, PHP und JDBC anzeigen. Kopieren Sie die ADO.NET Verbindungszeichenfolge, und fügen Sie den Wert in die app.config-Datei ein. Ersetzen Sie "{your_password_here}" durch Ihr Datenbankkennwort. (Angenommen, Sie haben die Skripts zum Bereitstellen der MVC-App verwendet, haben Sie das Datenbankkennwort im SqlDatabasePassword Skriptparameter angegeben.)

Das Ergebnis sollte wie folgt aussehen:

<add name="appdb" connectionString="Server=tcp:####.database.windows.net,1433;Database=appdb;User ID=####;Password=####;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;" providerName="System.Data.SqlClient" />

Ersetzen Sie in derselben MyFixIt.WorkerRole\app.config-Datei unter appSettingsdie beiden Platzhalterwerte für das Azure-Speicherkonto.

<appSettings>
  <add key="StorageAccountName" value="{StorageAccountName}" />
  <add key="StorageAccountAccessKey" value="{StorageAccountAccessKey}" />
</appSettings>

Sie können den Zugriffsschlüssel über das Portal abrufen. Weitere Informationen finden Sie unter Verwalten von Speicherkonten.

Ersetzen Sie in MyFixItCloudService\ServiceConfiguration.Cloud.cscfg die gleichen beiden Platzhalterwerte für das Azure-Speicherkonto.

<ConfigurationSettings>
    <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" 
             value="DefaultEndpointsProtocol=https;AccountName={StorageAccountName};AccountKey={StorageAccountAccessKey}" />
  </ConfigurationSettings>

Jetzt können Sie den Clouddienst bereitstellen. Klicken Sie unter Projektmappen durchsuchen mit der rechten Maustaste auf das Projekt MyFixItCloudService, und wählen Sie Veröffentlichen aus. Weitere Informationen finden Sie in Teil 2 dieses Tutorials unter Bereitstellen der Anwendung in Azure.