WebApi列子(回転)
12122 ワード
1.WebApiとは何か
ASP.NET Web APIは、ブラウザおよびモバイルデバイスを含む複数のクライアントによってアクセス可能なHTTPサービスを容易に構築するためのフレームワークである.ASP.NET Web APIは、.NET Framework上でRESTfulアプリケーションの理想的なプラットフォームを構築します.
WebApiをAspと見なすことができます.Netプロジェクトタイプの1つで、よく知られているWebFormプロジェクト、Windowsフォームプロジェクト、コンソールアプリケーションなどの他のプロジェクトタイプです.
WebApiタイプのプロジェクトの最大の利点は、開発者がクライアントとサーバ間で伝送されるデータのシーケンス化と逆シーケンス化の問題を心配する必要がないことです.WebApiは強いタイプなので、自動的にシーケンス化と逆シーケンス化を行うことができ、後でプロジェクトで見ることができます.
次に、WebApiタイプのプロジェクトを構築し、プロジェクトでは製品Productを追加削除し、ProductのデータをList<>リスト(メモリ)に格納します.
2.ページ実行効果
図に示すように、レコードを追加できます.レコードのIdを入力し、そのレコードの他の情報を照会する.このIdのレコードを変更する.Idのレコードを削除します.
3.何も言わずにプロジェクトを始める
1)「ASP.NET MVC 4 Webアプリケーション」プロジェクトを新規作成し、「ProductStore」と命名し、「OK」をクリックし、図のように
2)テンプレート「Web API」を選択し、図のように確定をクリックする
3)MVCタイプの項目と同様に,ビルドプロセスは,まずデータ・モデル(Model)を構築してデータにアクセスし,コントローラ・レイヤ(Controller)を構築して送信されたHttp要求を処理し,最後に表示レイヤ(View)を構築してユーザの入力を受信してユーザの進行と直接対話する.
ここではまずModelsフォルダに製品Productクラス:Productを作成します.cs、以下の通りです.using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ProductStore.Models
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
}
4)考えてみると、私たちは現在1つのProductタイプのオブジェクトしかありません.私たちは1つのクラスを作成してそれに対して添削改ざんを実現しなければなりません.後で他のタイプのオブジェクトを増やす可能性があります.新しいタイプのオブジェクトに対して添削改ざんを行うクラスを作成する必要があります.拡張と呼び出しを容易にするために、Productの上にインタフェースを構築し、このインタフェースに添削改ざんの方法名とパラメータを約束させます.Modelsフォルダに新しいインタフェースを作成しました:IProductRepository.cs、以下の通りです.using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProductStore.Models
{
interface IProductRepository
{
IEnumerable GetAll();
Product Get(int id);
Product Add(Product item);
void Remove(int id);
bool Update(Product item);
}
}
5)次に,このインタフェースを実装し,Modelsフォルダにクラスを新規作成し,具体的にはProductタイプのオブジェクトに対してアクセスデータを添削し,そのクラスの構築方法でリストリストにいくつかのデータを格納する.cs、以下の通りです.using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ProductStore.Models
{
public class ProductRepository:IProductRepository
{
private List products = new List();
private int _nextId = 1;
public ProductRepository()
{
Add(new Product { Name="Tomato soup",Category="Groceries",Price=1.39M});
Add(new Product { Name="Yo-yo",Category="Toys",Price=3.75M});
Add(new Product { Name = "Hammer", Category = "Hardware", Price = 16.99M });
}
public IEnumerable GetAll()
{
return products;
}
public Product Get(int id)
{
return products.Find(p=>p.Id==id);
}
public Product Add(Product item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
item.Id = _nextId++;
products.Add(item);
return item;
}
public void Remove(int id)
{
products.RemoveAll(p=>p.Id==id);
}
public bool Update(Product item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
int index = products.FindIndex(p=>p.Id==item.Id);
if (index == -1)
{
return false;
}
products.RemoveAt(index);
products.Add(item);
return true;
}
}
}
このとき,Model層が構築される.
6)次に,Controller層を構築する前に,Httpにおけるいくつかの要求タイプを以下のようにレビューする.
getタイプは、サーバ側からデータを取得するために使用され、サーバ側に操作や影響を与えるべきではありません.
postタイプは、サーバ側にデータを送信し、サーバ側に影響を与える新しいデータを作成するために使用されます.
putタイプは、サーバ側にデータを更新し、サーバ側に影響を与えるために使用されます(新しいデータを作成することもできますが、推奨されません).
deleteタイプは、サーバ側に影響を与えるデータを削除するために使用されます.
これにより、4つのリクエストタイプは、データのクエリー、追加、変更、削除に対応します.WebApiもおすすめです.WebApiプロジェクトでは、特定のページではなく、各コントローラのメソッドを要求します(コントローラも種類で、デフォルトはControllersフォルダにあります).次はProductControllerを作成します.csコントローラクラスは、いずれの方法も「Get Post Put Delete」のいずれかで始まる.このような冒頭はGetタイプのリクエストをGetで始まる方法で処理し、PostタイプのリクエストをPostで始まる方法で処理し、PutとDeleteは同じである.
Getで始まる方法はいくつかあっても良いのですが、このときどの方法で実行するのかをどのように区別しますか?これはGetの先頭にあるメソッドの入力パラメータに依存し,コードで後で分解できる.Controller層を構築し、ControllersフォルダにProductControllerを作成する.csコントローラクラスは以下の通りです.using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ProductStore.Models;
using System.Web.Http;
using System.Net;
using System.Net.Http;
namespace ProductStore.Controllers
{
public class ProductsController : ApiController
{
static readonly IProductRepository repository = new ProductRepository();
//GET: /api/products
public IEnumerable GetAllProducts()
{
return repository.GetAll();
}
//GET: /api/products/id
public Product GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return item;
}
//GET: /api/products?category=category
public IEnumerable GetProductsByCategory(string category)
{
return repository.GetAll().Where(p=>string.Equals(p.Category,category,StringComparison.OrdinalIgnoreCase));
}
//POST: /api/products
public HttpResponseMessage PostProduct(Product item)
{
item = repository.Add(item);
var response = Request.CreateResponse(HttpStatusCode.Created,item);
string uri = Url.Link("DefaultApi", new { id=item.Id});
response.Headers.Location = new Uri(uri);
return response;
}
//PUT: /api/products/id
public void PutProduct(int id, Product product)
{
product.Id = id;
if (!repository.Update(product))
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
}
//Delete: /api/products/id
public void DeleteProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
repository.Remove(id);
}
}
}
このクラスをApiControllerクラスに継承し、各種Get,Post,Put,DeleteタイプHttpリクエストを処理する方法を実装する.
各メソッドの前にコメントがあり、メソッドの最初に依存するリクエストのタイプと、メソッドをリクエストするurlを識別します.
これらのurlは規則的で、下図を参照してください.
apiは必須で、productsはProductsControllersコントローラに対応し、その後、Httpリクエストのタイプとurlの後アドレスが決定されます.
ここでは,3番目の「Get a product by category」を除いて,他の方法を実現した.
7)最後に,ビューレイヤを構築し,ビューフォルダ内のホームフォルダの下のIndexを変更する.cshtmlファイル、このファイルはプロジェクト起動ページで、以下の通りです.
Name:
Category:
Price:
Id:
Name:
Category:
Price:
8) に、ページにjsコードを し、 のボタンイベントに して、Httpリクエストを します. のようにします.
//
var Product = {
create: function () {
Id: "";
Name: "";
Category: "";
Price: "";
return Product;
}
}
// :POST url: /api/Products
// ProductsController.cs public HttpResponseMessage PostProduct(Product item)
$("#addItem").click(function () {
var newProduct = Product.create();
newProduct.Name = $("#name").val();
newProduct.Category = $("#category").val();
newProduct.Price = $("#price").val();
$.ajax({
url: "/api/Products",
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(newProduct),
success: function () {
alert(" !");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(" , :" + textStatus + " " + errorThrown);
}
});
});
// Id :GET url: /api/Products/Id
// ProductsController.cs public Product GetProduct(int id)
$("#showItem").click(function () {
var inputId = $("#id2").val();
$("#name2").val("");
$("#category2").val("");
$("#price2").val("");
$.ajax({
url: "/api/Products/" + inputId,
type: "GET",
contentType: "application/json; charset=urf-8",
success: function (data) {
$("#name2").val(data.Name);
$("#category2").val(data.Category);
$("#price2").val(data.Price);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(" , :" + textStatus + " " + errorThrown);
}
});
});
// Id :PUT url: /api/Products/Id
// ProductsController.cs public void PutProduct(int id, Product product)
$("#editItem").click(function () {
var inputId = $("#id2").val();
var newProduct = Product.create();
newProduct.Name = $("#name2").val();
newProduct.Category = $("#category2").val();
newProduct.Price = $("#price2").val();
$.ajax({
url: "/api/Products/" + inputId,
type: "PUT",
data: JSON.stringify(newProduct),
contentType: "application/json; charset=urf-8",
success: function () {
alert(" ! ");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(" , :" + textStatus + " " + errorThrown);
}
});
});
// Id :DELETE url: /api/Products/Id
// ProductsController.cs public void DeleteProduct(int id)
$("#removeItem").click(function () {
var inputId = $("#id2").val();
$.ajax({
url: "/api/Products/" + inputId,
type: "DELETE",
contentType: "application/json; charset=uft-8",
success: function (data) {
alert("Id " + inputId + " !");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(" , :" + textStatus + " " + errorThrown);
}
});
});
ここで、WebApiの簡単な添削変更項目が完成し、実行項目を選択すればテストできます.なお、ajaxで要求を開始する場合、サーバ側に送信データは直接json文字列であり、もちろんこのjson文字列の各フィールドはProductとなる.csクラスの各フィールドは同名に対応しており,サーバ側でデータを受信した場合,受信したデータをシーケンス化することはなく,クライアントにデータを返す場合もデータを逆シーケンス化することはなく,従来の開発でシーケンス化と逆シーケンス化を繰り返す時間を大幅に節約した.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ProductStore.Models
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProductStore.Models
{
interface IProductRepository
{
IEnumerable GetAll();
Product Get(int id);
Product Add(Product item);
void Remove(int id);
bool Update(Product item);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ProductStore.Models
{
public class ProductRepository:IProductRepository
{
private List products = new List();
private int _nextId = 1;
public ProductRepository()
{
Add(new Product { Name="Tomato soup",Category="Groceries",Price=1.39M});
Add(new Product { Name="Yo-yo",Category="Toys",Price=3.75M});
Add(new Product { Name = "Hammer", Category = "Hardware", Price = 16.99M });
}
public IEnumerable GetAll()
{
return products;
}
public Product Get(int id)
{
return products.Find(p=>p.Id==id);
}
public Product Add(Product item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
item.Id = _nextId++;
products.Add(item);
return item;
}
public void Remove(int id)
{
products.RemoveAll(p=>p.Id==id);
}
public bool Update(Product item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
int index = products.FindIndex(p=>p.Id==item.Id);
if (index == -1)
{
return false;
}
products.RemoveAt(index);
products.Add(item);
return true;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ProductStore.Models;
using System.Web.Http;
using System.Net;
using System.Net.Http;
namespace ProductStore.Controllers
{
public class ProductsController : ApiController
{
static readonly IProductRepository repository = new ProductRepository();
//GET: /api/products
public IEnumerable GetAllProducts()
{
return repository.GetAll();
}
//GET: /api/products/id
public Product GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return item;
}
//GET: /api/products?category=category
public IEnumerable GetProductsByCategory(string category)
{
return repository.GetAll().Where(p=>string.Equals(p.Category,category,StringComparison.OrdinalIgnoreCase));
}
//POST: /api/products
public HttpResponseMessage PostProduct(Product item)
{
item = repository.Add(item);
var response = Request.CreateResponse(HttpStatusCode.Created,item);
string uri = Url.Link("DefaultApi", new { id=item.Id});
response.Headers.Location = new Uri(uri);
return response;
}
//PUT: /api/products/id
public void PutProduct(int id, Product product)
{
product.Id = id;
if (!repository.Update(product))
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
}
//Delete: /api/products/id
public void DeleteProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
repository.Remove(id);
}
}
}
Name:
Category:
Price:
Id:
Name:
Category:
Price: