前書き
ASP.NET Coreテクノロジー、エンティティフレームワーク、Microsoft SQL Server DBMS、およびAngularフレームワークを使用して単純なWebアプリケーションを作成する方法に関する短いコース。Postmanアプリケーションを介してWebAPIをテストします。
このコースはいくつかのパートで構成されています。
- ASP.NET WebAPIとEntityFrameworkCoreを使用してWebAPIを構築します。
- Angularでのユーザーインターフェイスの実装。
- アプリケーションに認証を追加します。
- アプリケーションモデルを拡張し、エンティティフレームワークの追加機能を調べます。
パート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フレームワークを使用してユーザーインターフェイスを実装します。