ASP.NET Web API +エンティティフレームワーク+ Microsoft SQL Server + Angular。パート1





前書き



ASP.NET Coreテクノロジー、エンティティフレームワーク、Microsoft SQL Server DBMS、およびAngularフレームワークを使用して単純なWebアプリケーションを作成する方法に関する短いコース。Postmanアプリケーションを介してWebAPIをテストします



このコースはいくつかのパートで構成されています。



  1. ASP.NET WebAPIとEntityFrameworkCoreを使用してWebAPIを構築します。
  2. Angularでのユーザーインターフェイスの実装。
  3. アプリケーションに認証を追加します。
  4. アプリケーションモデルを拡張し、エンティティフレームワークの追加機能を調べます。


パート1。ASP.NETWebAPIとEntityFrameworkCoreを使用してWebAPIを構築する



例として、やることリストの今では古典的なアプリケーションを考えてみましょう。アプリケーションを開発するために、私はVisual Studio 2019を使用します(Visual Studio 2017では、プロセスは同様です)。



プロジェクトの作成



Visual Studioで新しいASP.NETコアWebアプリケーションプロジェクトを作成します。アプリケーションに







名前を付け、プロジェクトのあるディレクトリへのパスを指定します。







そして、APIアプリケーションテンプレートを選択します。







モデル



モデルカタログを作成し、最初のTodoItem.csクラスを新しいカタログに追加しましょう。そのオブジェクトは、アプリケーションのToDoリストのいくつかのタスクを記述します。



public class TodoItem
{
    public int Id { get; set; }
    public string TaskDescription { get; set; }
    public bool IsComplete { get; set; }
}


Sql ServerをDBMSとして使用し、データベースにはEntity Framework Coreを介してアクセスし、最初に、組み込みのNuGetパッケージマネージャーを介してフレームワークをインストールします。







エンティティフレームワークを操作するためのアプローチの1つは、「コードファースト」アプローチです。このアプローチの本質は、アプリケーションモデル(この場合、モデルは単一のクラス(TodoItem.cs)を表す)に基づいて、データベースの構造(テーブル、プライマリキー、リンク)が形成され、このすべての作業が「舞台裏」で直接行われることです。 SQLは使用しません。モデルクラスの前提条件は、プライマリキーフィールドの存在です。デフォルトでは、エンティティフレームワークは、サブストリング「id」が存在する名前の整数フィールドを検索し、それに基づいてプライマリキーを形成します。特別な属性を使用するか、Fluent APIの機能を使用して、この動作をオーバーライドできます。



エンティティフレームワークを操作する際の主要なコンポーネントは、テーブル内のデータに実際にアクセスするためのデータベースコンテキストクラスです。



public class EFTodoDBContext : DbContext
{
    public EFTodoDBContext(DbContextOptions<EFTodoDBContext> options) : base(options) 
    { }
    public DbSet<TodoItem> TodoItems{ get; set; }
}


基本クラスDbContextは、データベースコンテキストを作成し、エンティティフレームワークの機能へのアクセスを提供します。SQL Server



2017Expressを使用してアプリケーションデータを保存します接続文字列は、appsettings.jsonというJSONファイルに保存されます。



{
  "ConnectionStrings": {
    "DefaultConnection": "Server=.\\SQLEXPRESS;Database=Todo;Trusted_Connection=true"
  }
}


次に、次のコードをConfigureServices()メソッドに追加して、Startup.csクラスを変更する必要があります。



services.AddDbContext<EFTodoDBContext>(options => options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"]));


AddDbContext()メソッドは、EFTodoDBContextデータベースコンテキストクラス用にEntity FrameworkCoreによって提供されるサービスを構成します。 AddDbContext()メソッドの引数は、コンテキストクラスのデータベースを構成するオプションオブジェクトを受け取るラムダ式です。この場合、データベースはUseSqlServer()メソッドを使用し、接続文字列を指定して構成されます。



ITodoRepositoryインターフェースでタスクを操作するための基本的な操作を定義しましょう。



 public interface ITodoRepository
 {
    IEnumerable<TodoItem> Get();
    TodoItem Get(int id);
    void Create(TodoItem item);
    void Update(TodoItem item);
    TodoItem Delete(int id);
 }


このインターフェイスを使用すると、データウェアハウスの特定の実装について考える必要がなくなります。おそらく、DBMSまたはORMフレームワークの選択を正確に決定していなかったため、データアクセスを記述するクラスがこのインターフェイスから継承されます。

前述のように、ITodoRepositoryから継承し、データソースとしてEFTodoDBContextを使用するリポジトリを実装しましょう。



public class EFTodoRepository : ITodoRepository
{
    private EFTodoDBContext Context;
    public IEnumerable<TodoItem> Get()
    {
        return Context.TodoItems;
    }
    public TodoItem Get(int Id)
    {
        return Context.TodoItems.Find(Id);
    }
    public EFTodoRepository(EFTodoDBContext context)
    {
        Context = context;
    }
    public void Create(TodoItem item)
    {
        Context.TodoItems.Add(item);
        Context.SaveChanges();
    }
    public void Update(TodoItem updatedTodoItem)
    {
        TodoItem currentItem = Get(updatedTodoItem.Id);
        currentItem.IsComplete = updatedTodoItem.IsComplete;
        currentItem.TaskDescription = updatedTodoItem.TaskDescription;

        Context.TodoItems.Update(currentItem);
        Context.SaveChanges();
        }

    public TodoItem Delete(int Id)
    {
        TodoItem todoItem = Get(Id);

        if (todoItem != null)
        {
            Context.TodoItems.Remove(todoItem);
            Context.SaveChanges();
        }

        return todoItem;
    }    
}


コントローラ



以下で実装を説明するコントローラーは、EFTodoDBContextのデータコンテキストについては何も知りませんが、その作業ではITodoRepositoryインターフェイスのみを使用します。これにより、コントローラーを変更せずにデータソースを変更できます。このアプローチは、彼の著書「専門家向けASP.NETコアMVCのエンティティフレームワークコア2」で「ストレージ」パターンと呼ばれるアダムフリーマンです。



コントローラは、標準のHTTP要求メソッド(GET、POST、PUT、DELETE)のハンドラを実装します。これにより、TodoItem.csクラスで説明されているタスクの状態が変更されます。



TodoController.csクラスを次の内容でControllersディレクトリに追加します。



[Route("api/[controller]")]
public class TodoController : Controller
{
    ITodoRepository TodoRepository;

    public TodoController(ITodoRepository todoRepository)
    {
        TodoRepository = todoRepository;
    }

    [HttpGet(Name = "GetAllItems")]
    public IEnumerable<TodoItem> Get()
    {
        return TodoRepository.Get();
    }

    [HttpGet("{id}", Name = "GetTodoItem")]
    public IActionResult Get(int Id)
    {
        TodoItem todoItem = TodoRepository.Get(Id);

        if (todoItem == null)
        {
            return NotFound();
        }

        return new ObjectResult(todoItem);
    }

    [HttpPost]
    public IActionResult Create([FromBody] TodoItem todoItem)
     {
        if (todoItem == null)
        {
            return BadRequest();
        }
        TodoRepository.Create(todoItem);
        return CreatedAtRoute("GetTodoItem", new { id = todoItem.Id }, todoItem);
    }

    [HttpPut("{id}")]
    public IActionResult Update(int Id, [FromBody] TodoItem updatedTodoItem)
    {
        if (updatedTodoItem == null || updatedTodoItem.Id != Id)
        {
            return BadRequest();
        }

        var todoItem = TodoRepository.Get(Id);
        if (todoItem == null)
        {
            return NotFound();
        }

        TodoRepository.Update(updatedTodoItem);
        return RedirectToRoute("GetAllItems");
    }

    [HttpDelete("{id}")]
    public IActionResult Delete(int Id)
    {
        var deletedTodoItem = TodoRepository.Delete(Id);

        if (deletedTodoItem == null)
        {
            return BadRequest();
        }

        return new ObjectResult(deletedTodoItem);
    }
 }


クラス定義の前に、コントローラーにアクセスするためのルートテンプレートを説明する属性があります:[Route( "api / [controller]")]。 TodoControllerには、次のルートを介してアクセスできます:https:// <host ip>:<port> / api / todo。 [Controller]は、「Controller」の部分を省略して、コントローラークラスの名前を小文字で指定します。



TodoControllerの各メソッド定義の前に、[<HTTPメソッド>( "パラメーター"、名前= "メソッドエイリアス")]という形式の特別な属性が指定されます。この属性は、このメソッドによって処理されるHTTP要求、要求URIで渡されるパラメーター、および要求を再送信できるメソッドのエイリアスを決定します。属性を指定しない場合、デフォルトでは、MVCフレームワークは、メソッドの名前と要求で指定されたパラメーターに基づいて、要求を処理するためにコントローラーで最も適切なメソッドを見つけようとします。したがって、TodoControllerコントローラーでGet()メソッドの属性を指定しない場合は、HTTP要求でGETメソッドを使用して:https:// <host ip>:<port> / api / todo、インフラストラクチャは要求を処理するためにコントローラーのGet()メソッドを定義します。



コンストラクターでは、コントローラーはITodoRepositoryタイプのオブジェクトへの参照を受け取りますが、これまでのところ、MVCインフラストラクチャは、コントローラーの作成時にどのオブジェクトを置き換えるかを認識していません。この依存関係を一意に解決するサービスを作成する必要があります。このために、ConfigureServices()メソッドに次のコードを追加してStartup.csクラスにいくつかの変更を加えます。



services.AddTransient<ITodoRepository, EFTodoRepository>();


AddTransient <ITodoRepository、EFTodoRepository>()メソッドは、たとえばコントローラーでITodoRepositoryタイプのインスタンスが必要な場合は常に、EFTodoRepositoryクラスの新しいインスタンスを作成するサービスを定義します。



Startup.csクラスの完全なコード:



public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
        services.AddDbContext<EFTodoDBContext>(options => options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"]));
        services.AddTransient<ITodoRepository, EFTodoRepository>();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();
        app.UseRouting();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
 }


移行



エンティティフレームワークがモデルからデータベースとテーブルを生成するには、データベース移行プロセスを使用する必要があります。移行は、エンティティフレームワークと連携するようにデータベースを準備するコマンドのグループです。これらは、データベースの作成と同期に使用されます。コマンドは、Package ManagerConsoleとPowerShell(Developer Power Shell)の両方で実行できます。 Package Manager Consoleを使用して、Microsoft.EntityFrameworkCore.Toolsパッケージをインストールする必要があるEntity Frameworkを操作します







。PackageManagerConsoleを起動し、Add-MigrationInitialコマンドを実行します。











プロジェクトに新しいディレクトリが表示されます-移行クラスが保存され、Update-Databaseコマンドの実行後にデータベース内のオブジェクトが作成されることに基づいています:







Web APIの準備ができており、ローカルIIS Expressでアプリケーションを実行することにより、コントローラの動作をテストできます。



WebAPIのテスト



PostmanでTodoWebAPIという新しいリクエストのコレクションを作成しましょう。







データベースが空なので、最初に新しいタスクの作成をテストしましょう。コントローラでは、Create()メソッドがタスクの作成を担当します。タスクはPOSTメソッドによって送信されたHTTP要求を処理し、要求の本文にJSON形式のシリアル化されたTodoItemオブジェクトを含みます。 Create()メソッドのtodoItemパラメーターの前にある[FromBody]属性は、MVCフレームワークに、要求本文からTodoItemオブジェクトを逆シリアル化し、パラメーターとしてメソッドに渡すように指示します。新しいタスクを作成するためにwebAPIにリクエストを送信するリクエストをPostmanで作成しましょう。







タスクの作成が成功した後のCreate()メソッドは、エイリアス「GetTodoItem」を使用してリクエストをGet()メソッドにリダイレクトし、新しく作成されたタスクのIDをパラメータとして渡します。その結果、リクエストに応じて、作成されたタスクオブジェクトをJSON形式で受け取ります。



PUTメソッドを使用してHTTPリクエストを送信し、URI ID(https:// localhost:44370 / api / todo / 1)で作成済みのオブジェクトを指定し、リクエスト本文でJSON形式を変更したオブジェクトを渡すことで、データベース内のこのオブジェクトを変更します。 :







パラメータを指定せずにGETメソッドを使用したHTTPリクエストでは、データベース内のすべてのオブジェクトを受信します







。DELETEメソッドを使用してURIでオブジェクトのIDを指定したHTTPリクエスト(https:// localhost:44370 / api / todo / 2)は、データベースからオブジェクトを削除し、次のJSONを返します。リモートタスク:







以上です。次のパートでは、AngularJavaScriptフレームワークを使用してユーザーインターフェイスを実装します。



All Articles