当前位置: 代码迷 >> Web前端 >> ASP.NET Web API & Backbone (一) ―― Web API & Simple Get
  详细解决方案

ASP.NET Web API & Backbone (一) ―― Web API & Simple Get

热度:814   发布时间:2013-02-24 17:58:56.0
ASP.NET Web API & Backbone (1) ―― Web API & Simple Get
这个系列主要介绍如何使用Backbone搭建基于 ASP.NET Web API 的客户端(重点在于Backbone的使用)

 .NET 4.5 中的 ASP.NET Web API 使得我们可以快速搭建基于REST风格的服务应用,利用强大的客户端框架 Backbone 我们可以采用MVC的设计思路,
组织客户端Javascript模块(功能) 从而实现快速灵活的应用开发。

关于 ASP.NET Web API 的介绍,可以看我这篇博客:【ASP.NET】 Web Api (.NET 4.5)
关于 Backbone ,可以先看看官方介绍:http://backbonejs.org/

【服务端 Web API】
为了演示我设计了一个简单的应用:留言簿
首先是服务端的 Model:

namespace BackboneAndWebApi.Models
{
    public class Comment
    {
        public Comment() { }

        public Comment(string text, string author)
        {
            Text = text;
            Author = author;
        }

        public int ID { get; set; }

        [Required]
        public string Text { get; set; }

        [Required]
        [StringLength(10, ErrorMessage = "Author is too long! This was validated on the server.")]
        public string Author { get; set; }

        [Required]
        public string Email { get; set; }

        public string GravatarUrl
        {
            get
            {
                return HttpUtility.HtmlDecode(Gravatar.GetUrl(Email ?? "", 40, defaultImage: "retro", rating: GravatarRating.G));
            }
            set { }
        }
    }
}
当然要有增删改查,于是有了下面的 Repository 接口
namespace BackboneAndWebApi.Models
{
    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);
    }
}
具体实现采用内存数据存储:
namespace BackboneAndWebApi.Models
{

    public class DictionaryCommentRepository : ICommentRepository
    {
        int nextID = 0;
        Dictionary<int, Comment> comments = new Dictionary<int, Comment>();

        public IEnumerable<Comment> Get()
        {
            return comments.Values.OrderBy(comment => comment.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;
        }
    }
}
利用 Ninject 在 WebAPI 初始化时注入(InitialData 是 DictionaryCommentRepository 的子类,构造函数中加一些初始数据)
namespace BackboneAndWebApi
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Filters.Add(new ValidateAttribute());

            IKernel kernel = new StandardKernel();
            kernel.Bind<ICommentRepository>().ToConstant(new InitialData());
            config.DependencyResolver = new NinjectResolver(kernel);

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}
CommentsController 是 Web API 的实现类,实现了简单的GET
namespace BackboneAndWebApi.Controllers
{
    public class CommentsController : ApiController
    {
        ICommentRepository repository;

        public CommentsController(ICommentRepository repository)
        {
            this.repository = repository;
        }

        #region GET
        [Queryable]
        public IQueryable<Comment> GetComments()
        {
            return repository.Get().AsQueryable();
        }

        public Comment GetComment(int id)
        {
            Comment comment;
            if (!repository.TryGet(id, out comment))
                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
            return comment;
        }
        #endregion
    }
}
发布后,用Fiddler测试(别忘记加上 Accept: application/json 的Header,这样才会返回json格式的数据)


【客户端】
先加入 Backbone,可以上官网自己下载,或者直接用 Nuget : Install-Package Backbone.js 
通过下面的 HTML 可以对 Backbone 进行初步的理解:
这个“留言簿” 定义为 CommentModel 和 CommentView,View负责页面的描绘,Model则是对应服务端实体,model.fetch 取得数据,view.render 将取到的数据交给
underscore 的 template 生成HTML结果。其他一些细节请看下面代码中的注释。
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Comments Test Home Page</title>
    <link href="/Content/Demo.css" rel="stylesheet" type="text/css" />
    <script src="Scripts/jquery-1.9.0.min.js"></script>
    <script src="Scripts/underscore-1.4.3.js"></script>
    <script src="Scripts/backbone-0.9.9.js"></script>
</head>
<body>
    <nav>
        <div class="demo-navigation">
            <a href="default.htm"><<< Back</a> 
            | Demo 1 Simple Get |
            <a href="demo2-crud.htm">On to Demo 2 - Simple CRUD >>></a>
        </div>
    </nav>
    <div id="content">
        
        <div id="demo-actions">
            <div>
                <legend>Get Comments Demos</legend>
                <button id="getComments">Go!</button>
            </div>
        </div>
        <div id="article">
            <p>
                This first demo shows a very simple GET scenario. Click on the button to 
                use jQuery to retrieve JSON data from a Web API endpoint and then display 
                the contents of that payload in the UI.
            </p>
            <p>
                The code represents retrieving data in a manner that any developer familiar 
                with jQuery would understand.
            </p>
        </div>

        <ul id="comments">
        </ul>

        <!-- 模板 -->
        <script id="commentTemplate" type="text/html">
          <% _.each(comments, function(item) { %>
            <li class="comment">
                <header>
                  <div class="info">
                    <img src='<%= item.GravatarUrl %>' />
                    <strong><span><%= item.Author %></span></strong>
                  </div>
                </header>
                <div class="body">
                  <p><%= item.Text %></p>
                </div>
            </li>
          <% }); %>
        </script>

        <script type="text/javascript">
            var CommentModel = Backbone.Model.extend({
                // model 对应服务端的API URL
                url: 'api/comments'
            });
            var CommentView = Backbone.View.extend({
                // 将body作为一个View 
                el: 'body',
                // 加载模板
                template: _.template($('#commentTemplate').html()),
                // 绑定HTML上"Go!"按钮,调用 model.fetch 获取数据
                // model.fetch 会调用 Backbone.sync('read', model, options) 里面封装了ajax
                events: {
                    'click #getComments': function () {
                        this.model.fetch();
                    }
                },
                initialize: function () {
                    this.model.on('change', this.render, this);
                },
                render: function () {
                    var data = this.model.toJSON();
                    $('#comments').html(this.template({ comments: data }));
                    return this;
                }
            });
            
            $(function () {
                var view = new CommentView({ model: new CommentModel() });
            });
        </script>
    </div>
</body>
</html>
运行结果:


下面将详细介绍 Backbone 是如何调用 WebApi 的CRUD。




1楼Joyhen25分钟前
学习了
  相关解决方案