ASP.NET Web API实践系列07,获取数据, 使用Ninject实现依赖倒置,使用Konockout实现页面元素和视图模型的双向绑定

本篇接着上一篇"ASP.NET Web API实践系列06, 在ASP.NET MVC 4 基础上增加使用ASP.NET WEB API",尝试获取数据。

在Models文件夹下创建Comment类:

namespace MvcApplication5.Models
{
    public class Comment
    {
        public int ID { get; set; }
        public string Author { get; set; }
        public string Text { get; set; }
        public string Email { get; set; }
    }
}

在Repository文件夹下创建ICommentRepository接口:

using System.Collections.Generic;
using MvcApplication5.Models;

namespace MvcApplication5.Repository
{
    public interface ICommentRepository
    {
        IEnumerable<Comment> Get();
        bool TryGet(int id, out Comment comment);
        Comment Add(Comment comment);
        bool Delete(int id);
        bool Update(Comment comment);
    }
}

在Repository文件夹下创建CommentRepository类,实现ICommentRepository接口:

using  System.Collections.Generic;
using System.Linq;
using MvcApplication5.Models;

namespace MvcApplication5.Repository
{
    public class CommentRepository : ICommentRepository
    {
        private int nextID = 0;
        Dictionary<int, Comment>  comments = new Dictionary<int, Comment>();

        public CommentRepository()
        {
            Add(new Comment
            {
                ID = 1,
                Text = @"I sat here trying really hard to think of something profound to write for my comment but was left with nothing interesting to say other than this droning on and on that I‘m doing right now. But sometimes, droning on and on serves a purpose. For example, this comment appears more realistic without resorting to Lorem Ipsum.",
                Author = "Phil",
                Email = "[email protected]",
            });
            Add(new Comment
            {
                ID = 1,
                Text = "This is the best thing I‘ve ever seen! And trust me, I‘ve seen a lot. A whole lot.",
                Author = "Henrik",
                Email = "[email protected]"
            });
            Add(new Comment
            {
                ID = 2,
                Text = "Is this thing on? Because if it isn‘t on, we should really consider turning it on. Have you tried turning it on? I haven‘t. But you should consider it.",
                Author = "Eilon",
                Email = "[email protected]"
            });
            Add(new Comment
            {
                ID = 3,
                Text = "My computer‘s cupholder doesn‘t work, can you help? I tried calling tech support, but they keep laughing and I don‘t understand why. It‘s really not helpful.",
                Author = "Glenn",
                Email = "[email protected]"
            });
        }

        public IEnumerable<Comment> Get()
        {
            return comments.Values.OrderBy(c => c.ID);
        }

        public bool TryGet(int id, out Comment comment)
        {
            return comments.TryGetValue(id, out comment);
        }

        public Comment Add(Comment comment)
        {
            comment.ID = nextID++;
            comments[comment.ID] = comment;
            return comment;
        }

        public bool Delete(int id)
        {
            return comments.Remove(id);
        }

        public bool Update(Comment comment)
        {
            bool update = comments.ContainsKey(comment.ID);
            comments[comment.ID] = comment;
            return update;
        }
    }
}




右键"引用",在"管理NuGet"程序包中搜索、安装Ninject。

在ASP.NET Web API中,DefaultHttpControllerActivator默认使用DependencyResolver对象去激活目标HttpControlle,通过实现IDependencyResolver接口可自定义DependencyResolver,从而把Ninject引入。

using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;
using Ninject;

namespace MvcApplication5.Extension
{
    public class NinjectDependencyResolver : IDependencyResolver
    {
        private List<IDisposable> disposables = 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 disposables)
            {
                disposable.Dispose();
            }
        }

        private void AddDisposableService(object service)
        {
            IDisposable disposable = service as IDisposable;
            if (disposable != null && !disposables.Contains(disposable))
            {
                disposables.Add(disposable);
            }
        }
    }
}

在全局注册NinjectControllerFactory这个自定义控制器工厂。

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            ......

            NinjectDependencyResolver dependencyResolver = new NinjectDependencyResolver();
            dependencyResolver.Register<ICommentRepository, CommentRepository>();
            GlobalConfiguration.Configuration.DependencyResolver = dependencyResolver;
        }


创建名称为CommentsController空的API控制器,编写如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using MvcApplication5.Models;
using MvcApplication5.Repository;
using Ninject;

namespace MvcApplication5.Controllers
{
    public class CommentsController : ApiController
    {
        [Inject]
        public ICommentRepository CommentRepository { get; set; }

        #region 获取数据

        public IEnumerable<Comment> GetComments()
        {
            return CommentRepository.Get();
        }

        public Comment GetComment(int id)
        {
            Comment comment;
            if (!CommentRepository.TryGet(id, out comment))
            {
                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
            }
            return comment;
        }
        #endregion
    }
}


在HomeController中提供一个Index视图。

using System.Web.Mvc;

namespace MvcApplication5.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

    }
}


在Shared/_Layout.cshtml中:

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    @Styles.Render("~/Content/css")
    <link href="~/Content/Demo.css" rel="stylesheet" />
</head>
<body>
    @RenderBody()

    @Scripts.Render("~/bundles/jquery")
    @RenderSection("scripts", required: false)
</body>


在Home/Index.cshtml视图中,通过Knockout在页面元素和页面视图模型间实现双向绑定,通过jQuery把从后台获取到的集合赋值给前端的页面视图模型的comments字段,遍历页面视图模型的comments,使用模版把内容显示出来。

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div>
    <button id="getComments">获取评论</button>
</div>

<ul data-bind="template: { name: ‘commentTemplate‘, foreach: comments }">
</ul>

@section scripts
{
    <script src="~/Scripts/knockout-2.2.0.js"></script>
    <script type="text/javascript">

        viewModel = {
            comments: ko.observableArray([])
        };

        ko.applyBindings(viewModel);

        $(function() {
            $(‘#getComments‘).on("click", function() {
                viewModel.comments([]);

                $.get(‘/api/comments‘, function (data) {
                    viewModel.comments(data);
                });
            });
        });
    </script>
    <script id="commentTemplate" type="text/html">
        <li class="comment">
            <header>
                <div class="info">
                    <strong><span data-bind="text: Author"></span></strong>
                </div>
            </header>
            <div class="body">
                <p data-bind="text: Text"></p>

            </div>
        </li>
    </script>
}


参考资料:
http://www.cnblogs.com/artech/p/ioc-4-asp-net-web-api.html
https://code.msdn.microsoft.com/ASPNET-Web-API-JavaScript-d0d64dd7/sourcecode?

时间: 2024-10-12 16:16:44

ASP.NET Web API实践系列07,获取数据, 使用Ninject实现依赖倒置,使用Konockout实现页面元素和视图模型的双向绑定的相关文章

ASP.NET Web API实践系列04,通过Route等特性设置路由

ASP.NET Web API路由,简单来说,就是把客户端请求映射到对应的Action上的过程.在"ASP.NET Web API实践系列03,路由模版, 路由惯例, 路由设置"一文中,体验了通过模版.惯例.HTTP方法来设置路由,这种做法的好处是把路由模版统一放在了App_Start文件夹下的WebApiConfig类中,方便管理,但缺点是不够灵活. REST把一切都看成资源,有时候,一个资源连带子资源,比如Customer和Orders密切关联,我们可能希望输入这样的请求:cust

ASP.NET Web API实践系列05,消息处理管道

ASP.NET Web API的消息处理管道可以理解为请求到达Controller之前.Controller返回响应之后的处理机制.之所以需要了解消息处理管道,是因为我们可以借助它来实现对请求和响应的自定义处理.所有的请求被封装到HttpRequestMessage这个类中,所有的响应被封装到HttpResponseMessage这个类中. 既然消息处理管道是可扩展的,那么,ASP.NET Web API一定为我们准备了便于扩展的接口或抽象类,它就是HttpMessageHandler抽象类.

ASP.NET Web Api 实践系列(一)自我寄宿

从今天开始,研究ASP.NET Web Api(以下有时会简称Web Api).我会写一个实践系列专题,不一定成理论体系,只是遇到问题或心得,记下来.争取用一段较长的时间对ASP.NET Web Api有个较深入的理解.这里我是使用VS2013集成开发环境,如果版本不够,可以用NuGet去下载Web Api相关dll. 今天讨论自我寄宿Web Api. Web Api继承了WCF的优点,除了常规的Web寄宿(IIS)外,还可以在NET的控制台.WinForms等程序中寄宿.这里讲一讲在控制台中寄

ASP.NET Web API实践系列02,在MVC4下的一个实例, 包含EF Code First,依赖注入, Bootstrap等

本篇体验在MVC4下,实现一个对Book信息的管理,包括增删查等,用到了EF Code First, 使用Unity进行依赖注入,前端使用Bootstrap美化.先上最终效果: →创建一个MVC4项目,选择Web API模版. →在Models文件夹创建一个Book.cs类. namespace MyMvcAndWebApi.Models { public class Book { public int Id { get; set; } public string Name { get; set

ASP.NET Web API实践系列01,以ASP.NET Web Form方式寄宿

创建一个空的ASP.NET Web Form项目. 右键项目,添加新项,创建Web API控制器类,TestController. 删除掉TestController默认的内容,编写如下: using System.Web.Http; namespace WebApplication1 { public class TestController : ApiController { [AcceptVerbs("Get")] public string SayHello() { retur

ASP.NET Web API实践系列03,路由模版, 路由惯例, 路由设置

ASP.NET Web API的路由和ASP.NET MVC相似,也是把路由放在RouteTable中的.可以在App_Start文件夹中的WebApiConfig.cs中设置路由模版.默认的路由模版是: routes.MapHttpRoute( name: "API Default", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } );

ASP.NET Web API实践系列06, 在ASP.NET MVC 4 基础上增加使用ASP.NET WEB API

本篇尝试在现有的ASP.NET MVC 4 项目上增加使用ASP.NET Web API. 新建项目,选择"ASP.NET MVC 4 Web应用程序". 选择"基本"项目模版. 在Controllers文件夹下添加一个名称为"TestController"的空API控制器. 在引用文件夹中多了以下程序集:System.Web.HttpSystem.Web.Http.WebHostSystem.Net.HttpSystem.Net.Http.Fo

ASP.NET Web Api 实践系列(二)Get/Post方式调用Web Api

本文给出Get/Post方式访问Web Api的帮助方法,对于Put/Delete方式的调用跟Post调用类似. 一.Web Api调用帮助类 下面给出Web Api调用帮助类的代码: 1 using System; 2 using System.Collections.Generic; 3 using System.Net.Http; 4 using System.Net.Http.Headers; 5 using System.Text; 6 using System.Web; 7 8 na

Asp.Net Web API 2第九课——自承载Web API

前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html Asp.Net Web API可以需要IIS.你可以在你自己的主机上来承载一个Web API. 本教程来展示在控制台应用程序中来承载一个Web API.使用的开发工具为VS2013. 本文示例代码下载链接http://pan.baidu.com/s/1d56zf 创建一个控制台应用程序 这里我默认的Framework版本为4