zoukankan      html  css  js  c++  java
  • MVC项目实践,在三层架构下实现SportsStore-09,ASP.NET MVC调用ASP.NET Web API的查询服务

    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":

    40

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

    在即将创建的控制器中,会用到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
    38

    以上,说明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 {
                 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"设置为启动项目,运行:
    39

    至此,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实现增删改查

  • 相关阅读:
    [android] 实现返回键操作思路
    [android] 切换界面的问题
    [android] 切换界面的通用处理
    [android] 界面切换的简单动画
    [android] 界面切换的核心方法
    [android] 标题部分管理
    [android] 界面的划分
    [android] socket在手机上的应用
    [android] 网络链接类型和渠道
    [android] android通信协议
  • 原文地址:https://www.cnblogs.com/darrenji/p/3823976.html
Copyright © 2011-2022 走看看