ASP.NET Web API和WCF都体现了REST软件架构风格。在REST中,把一切数据视为资源,所以也是一种面向资源的架构风格。所有的资源都可以通过URI来唯一标识,通过对资源的HTTP操作(GET/HEAD、POST、PUT和DELETE),使资源的表征状态发生了改变,即Representational State Transfer,缩写为REST。

WCF从3.5以来,也体现了REST的架构风格,但对于一般的消息通信来说,显得"过重",所以,微软推出ASP.NET Web API,提供一种"轻量级"的服务,并且借鉴了MVC,以Controller的形式来定义服务,而Controller中的Action方法对应着不同的HTTP操作。

本篇为"在三层架构下实现SportsStore"系列的第九篇,包括:

■ 11、ASP.NET MVC调用ASP.NET Web API的增删改查服务
    □ 11.1 调用查询服务
        ※ 11.1.1 创建ASP.NET Web API项目 引入Ninject
        ※ 11.1.2 提供ASP.NET WEB API增删改查服务
        ※ 11.1.3 ASP.NET MVC调用ASP.NET WEB API查询服务

11、ASP.NET MVC调用ASP.NET Web API提供增删改查服务

11.1 调用查询服务

11.1.1 创建ASP.NET Web API项目 引入Ninject

在解决方案下创建一个空的"ASP.NET Web API 2空项目",名称为"MySportsStore.WebApi":

在MySportsStore.WebApi"下添加如下引用:
● MySportsStore.BLL
● MySportsStore.IBLL
● MySportsStore.Model
● 通过GuGet安装最新版的EntityFramework
● 通过NuGet安装Ninject

在即将创建的控制器中,会用到IProductService及其实现,我们需要借助Ninject来管理接口和实现类。在"MySportsStore.WebApi"下,创建一个System.Web.Http.Dependencies.IDependencyResolver接口的类:

using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;
using Ninject; namespace MySportsStore.WebApi.Extension
{
public class NinjectDependencyResolver : IDependencyResolver
{
private List<IDisposable> disposableServices = new List<IDisposable>();
public IKernel Kernel { get; private set; } public NinjectDependencyResolver(NinjectDependencyResolver parent)
{
this.Kernel = parent.Kernel;
} public NinjectDependencyResolver()
{
this.Kernel = new StandardKernel();
} public void Register<TFrom, TTO>() where TTO : TFrom
{
this.Kernel.Bind<TFrom>().To<TTO>();
} public IDependencyScope BeginScope()
{
return new NinjectDependencyResolver(this);
} public object GetService(System.Type serviceType)
{
return this.Kernel.TryGet(serviceType);
} public System.Collections.Generic.IEnumerable<object> GetServices(System.Type serviceType)
{
foreach (var service in this.Kernel.GetAll(serviceType))
{
this.AddDisposableService(service);
yield return service;
}
} public void Dispose()
{
foreach (IDisposable disposable in disposableServices)
{
disposable.Dispose();
}
} private void AddDisposableService(object service)
{
IDisposable disposable = service as IDisposable;
if (null != disposable && !disposableServices.Contains(disposable))
{
disposableServices.Add(disposable);
}
}
}
}

然后在全局中注册:

using System.Web.Http;
using MySportsStore.BLL;
using MySportsStore.IBLL;
using MySportsStore.WebApi.Extension; namespace MySportsStore.WebApi
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register); NinjectDependencyResolver dependencyResolver = new NinjectDependencyResolver();
dependencyResolver.Register<IProductService, ProductService>();
GlobalConfiguration.Configuration.DependencyResolver = dependencyResolver;
}
}
}

11.1.2 提供ASP.NET WEB API增删改查服务

在"MySportsStore.WebApi"下,创建ProductApi控制器,提供增删改查服务,实现如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using MySportsStore.IBLL;
using MySportsStore.Model;
using Ninject; namespace MySportsStore.WebApi.Controllers
{
public class ProductApiController : ApiController
{
[Inject]
public IProductService ProductService { get; set; } public ProductApiController()
{
this.DisposableObjects = new List<IDisposable>();
this.AddDisposableObject(ProductService);
} // GET api/productapi
public IEnumerable<Product> Get()
{
return ProductService.LoadEntities(p => true).AsEnumerable();
} // GET api/productapi/5
public Product Get(int id)
{
return ProductService.LoadEntities(p => p.Id == id).FirstOrDefault();
} // POST api/productapi
public void Post(Product product)
{
var dbProduct = ProductService.LoadEntities(p => p.Id == product.Id).FirstOrDefault();
ProductService.UpdateEntity(dbProduct);
} // PUT api/productapi/5
public void Put(Product product)
{
ProductService.AddEntity(product);
} // DELETE api/productapi/5
public void Delete(int id)
{
var product = ProductService.LoadEntities(p => p.Id == id).FirstOrDefault();
ProductService.DeleteEntity(product);
} #region 手动垃圾回收逻辑
protected IList<IDisposable> DisposableObjects { get; private set; } protected void AddDisposableObject(object obj)
{
IDisposable disposable = obj as IDisposable;
if (disposable != null)
{
this.DisposableObjects.Add(disposable);
}
} protected override void Dispose(bool disposing)
{
if (disposing)
{
foreach (IDisposable obj in this.DisposableObjects)
{
if (null != obj)
{
obj.Dispose();
}
}
}
base.Dispose(disposing);
}
#endregion
}
}

以上,通过Ninject把IProductService注入到ProductService属性上,然后使用ProductService实现增删改查,并实现了手动垃圾回收。

把"MySportsStore.WebApi"设置为启动项目,在浏览器输入:http://localhost:1577/api/productapi

以上,说明AP.NET WEB API查询数据服务是正常的。这里的地址,也就是代表查询状态的唯一URI,通过这个URI,无论你使用何种语言,无论是通过手机客户端、平板客户端、电脑客户端......你都可以调用这个REST风格的服务。

11.1.3 ASP.NET MVC调用ASP.NET WEB API查询服务

在MVC中,使用HttpClient来获取ASP.NET WEB API的服务,以下通过异步方式查询来自ASP.NET WEB API的数据:

using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using MySportsStore.Model;
using Newtonsoft.Json; namespace MySportsStore.WebUI.RESTServices
{
public class ProductRESTService
{
readonly string uri = "http://localhost:1577/api/productapi"; public async Task<List<Product>> GetProductsAsync()
{
using (HttpClient httpClient = new HttpClient())
{
return JsonConvert.DeserializeObject<List<Product>>(
await httpClient.GetStringAsync(uri)
);
}
}
}
}

在"MySportsStore.WebUI"下,创建Home控制器:

using System.Threading.Tasks;
using System.Web.Mvc;
using MySportsStore.WebUI.RESTServices; namespace MySportsStore.WebUI.Controllers
{
public class HomeController : Controller
{
private ProductRESTService service = new ProductRESTService(); public async Task<ActionResult> Index()
{
return View("Index",
await service.GetProductsAsync()
);
} }
}

在"MySportsStore.WebUI"下,创建Home/Index.cshtml视图:

@model IEnumerable<MySportsStore.Model.Product>
@{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="~/Scripts/jquery-1.8.2.js"></script>
<style type="text/css">
table {
width: 1000px;
border: 1px solid #000000;
background-color: #eee;
} table tr {
line-height: 20px;
border-bottom: 1px solid black;
} table th {
background-color: #ccc;
color: #fff;
} .oddRow {
background-color: #fff;
} #products {
border: 0px solid red;
}
</style>
</head>
<body>
<div id="products">
<table>
<tr class="oddRow">
<th>编号</th>
<th>类别</th>
<th>名称</th>
<th>价格</th>
<th>描述</th>
</tr>
@foreach (var product in Model)
{
<tr>
<td>@product.Id</td>
<td>@product.Category</td>
<td>@product.Name</td>
<td>@product.Price.ToString("c")</td>
<td>@product.Description</td>
</tr>
}
</table>
</div>
</body>
</html>

把"MySportsStore.WebUI"设置为启动项目,运行:

至此,ASP.NET MVC调用ASP.NET Web API的查询服务结束。

参考资料:
引入Ninject部分,参考了蒋金楠(Artech)的"IoC在ASP.NET Web API中的应用"

源码在这里

“MVC项目实践,在三层架构下实现SportsStore”系列包括:

MVC项目实践,在三层架构下实现SportsStore,从类图看三层架构

MVC项目实践,在三层架构下实现SportsStore-01,EF Code First建模、DAL层等

MVC项目实践,在三层架构下实现SportsStore-02,DbSession层、BLL层

MVC项目实践,在三层架构下实现SportsStore-03,Ninject控制器工厂等

MVC项目实践,在三层架构下实现SportsStore-04,实现分页

MVC项目实践,在三层架构下实现SportsStore-05,实现导航

MVC项目实践,在三层架构下实现SportsStore-06,实现购物车

MVC项目实践,在三层架构下实现SportsStore-07,实现订单提交

MVC项目实践,在三层架构下实现SportsStore-08,部署到IIS服务器

MVC项目实践,在三层架构下实现SportsStore-09,ASP.NET MVC调用ASP.NET Web API的查询服务

MVC项目实践,在三层架构下实现SportsStore-10,连接字符串的加密和解密

MVC项目实践,在三层架构下实现SportsStore-11,使用Knockout实现增删改查

MVC项目实践,在三层架构下实现SportsStore-09,ASP.NET MVC调用ASP.NET Web API的查询服务的更多相关文章

  1. MVC项目实践,在三层架构下实现SportsStore,从类图看三层架构

    在"MVC项目实践,在三层架构下实现SportsStore-02,DbSession层.BLL层"一文的评论中,博友浪花一朵朵建议用类图来理解本项目的三层架构.于是就有了本篇: I ...

  2. MVC项目实践,在三层架构下实现SportsStore-02,DbSession层、BLL层

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  3. MVC项目实践,在三层架构下实现SportsStore-01,EF Code First建模、DAL层等

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  4. MVC项目实践,在三层架构下实现SportsStore-03,Ninject控制器工厂等

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  5. MVC项目实践,在三层架构下实现SportsStore-04,实现分页

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  6. MVC项目实践,在三层架构下实现SportsStore-05,实现导航

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  7. MVC项目实践,在三层架构下实现SportsStore-06,实现购物车

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  8. MVC项目实践,在三层架构下实现SportsStore-07,实现订单提交

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  9. MVC项目实践,在三层架构下实现SportsStore-08,部署到IIS服务器

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

随机推荐

  1. 字符编解码的故事(ASCII,ANSI,Unicode,Utf-8区别)

    (关于字符编码的深入解释,请参见我的原创文章<关于字符编码,你所需要知道的>.) 此文为转载,有少许修订,原文出处不详. 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同 ...

  2. windows 下安装Yii2 高级版本

    1.  首先安装 Composer 2.  执行  composer global require "fxp/composer-asset-plugin:~1.1.1" 3. 执行 ...

  3. 免费api大全(更新中)

    免费api大全(更新中) API大全  http://www.apidq.com/    (这个碉堡了) 天气接口 气象局接口 完整数据:http://m.weather.com.cn/data/10 ...

  4. wordpress 自定义面板显示不了挂件区问题

    刚才在写一个wordpress主题,遇到一个问题.注册好的挂件区在控制面板(dashboard)上显示,在自定义面板上却不显示. 查询了下,发现几个老外朋友也遇到了这个问题: http://wordp ...

  5. Oracle EBS 术语解释

    SRS:是否在标准窗口进行提交请求 fnd_flex_value_sets.validation_type含义如下: D:从属I:独立N:无P:对U:特定F:表X:可转换独立Y:可转换从属

  6. jboss中文支持

    一.中文问题 如果操作系统不支持中文, 应首先使操作系统上的Server支持中文. 修改run.conf中 -Dfile.encoding=gbk -Ddefault.client.encoding= ...

  7. VCL自带的TabControl真心不好用...

    不是说功能, 而是指自绘能力, 开启OwnerDraw以后, 画是可以画了, 可是为啥每个Tab页头的边框不能变捏 只能是灰秃秃的, 感觉很不和谐 RZ的TabControl很强大, 可惜想用它需要带 ...

  8. CC254x(cc2540/cc2541)的微信AirSync调试笔记

    一.前言 本尊自诩为IOT小能手,一直没涉足蓝牙实在说不过去.刚好上个月底的时候计划做个BLE设备,这阵子利用业余时间自学了BLE协议栈,了解了GATT,磕磕绊绊完成CC254x(cc2540/cc2 ...

  9. NSArry的常见方法

    使用数组对象创建的数组功能非常强大,在Java语言或者C语言中定义的数组必须满足数组中的每一个元素必须是同样的类型.而Objective-C语言可以在Array数组中放任意类型的数据,值得注意的是只能 ...

  10. Java高级之虚拟机加载机制

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 1.0版本:2016-05-21 SubClass!! 执行结果说明一个问题:子类调用父类变量的时候 ...