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


    本篇体验在MVC4下,实现一个对Book信息的管理,包括增删查等,用到了EF Code First, 使用Unity进行依赖注入,前端使用Bootstrap美化。先上最终效果:

    3


    →创建一个MVC4项目,选择Web API模版。

    1

     

    →在Models文件夹创建一个Book.cs类。

    namespace MyMvcAndWebApi.Models
    
    {
    
        public class Book
    
        {
    
            public int Id { get; set; }
    
            public string Name { get; set; }
    
            public decimal Price { get; set; }
    
        }
    
    }

    →在Models文件夹创建BookInitializer类,用来初始化数据库表数据。

    using System.Data.Entity;
    
    namespace MyMvcAndWebApi.Models
    
    {
    
        public class BookInitializer : DropCreateDatabaseIfModelChanges<BookStore>
    
        {
    
            protected override void Seed(BookStore context)
    
            {
    
                context.Books.Add(new Book() {Name = "我有一头小毛驴", Price = 200M});
    
                context.Books.Add(new Book() { Name = "今天天气真好", Price = 300M });
    
                context.Books.Add(new Book() { Name = "秋天是落叶的季节", Price = 500M });
    
            }
    
        }
    
    }
    

     

    →在Models文件夹中,创建BookStore类,派生于DbContext。

    using System.Data.Entity;
    
    namespace MyMvcAndWebApi.Models
    
    {
    
        public class BookStore : DbContext
    
        {
    
            public BookStore() : base("conn")
    
            {
    
                Database.SetInitializer(new BookInitializer());
    
            }
    
           public  DbSet<Book> Books { get; set; } 
    
        }
    
    }
    

     

    →在Web.config中配置连接字符串。

      <connectionStrings>
    
        ......
    
       <add name="conn" connectionString="Data Source=.;User=yourusername;Password=yourpassword;Initial Catalog=BookStore;Integrated Security=True" providerName="System.Data.SqlClient" />
    
      </connectionStrings>

     

    →Repository首先需要一个接口,在Models文件夹中创建IBookRepository接口。

    using System.Collections.Generic;
    
    namespace MyMvcAndWebApi.Models
    
    {
    
        public interface IBookRepository
    
        {
    
            IEnumerable<Book> GetAll();
    
            Book Get(int id);
    
            Book Add(Book book);
    
            void Remove(int id);
    
            bool Update(Book book);
    
        }
    
    }
    

     

     

    →实现IBookRepository接口,用到BookStore这个上下文。

    using System.Collections.Generic;
    
    using System.Data;
    
    namespace MyMvcAndWebApi.Models
    
    {
    
        public class BookRepository : IBookRepository
    
        {
    
            private BookStore db = new BookStore();
    
            public BookRepository(){}
    
            public IEnumerable<Book> GetAll()
    
            {
    
                return db.Books;
    
            }
    
            public Book Add(Book book)
    
            {
    
                db.Books.Add(book);
    
                db.SaveChanges();
    
                return book;
    
            }
    
            public void Remove(int id)
    
            {
    
                Book book = db.Books.Find(id);
    
                db.Books.Remove(book);
    
                db.SaveChanges();
    
            }
    
            public bool Update(Book book)
    
            {
    
                db.Entry(book).State = EntityState.Modified;
    
                db.SaveChanges();
    
                return true;
    
            }
    
            public Book Get(int id)
    
            {
    
                return db.Books.Find(id);
    
            }
    
        }
    
    }
    

     

    →有了接口和实现,接下来会用到依赖注入。选择使用Unity,在NuGet中下载。
    2

     

    →首先需要一个依赖注入容器。在项目下创建Helper文件夹,在其中创建IoCContainer类。

    using System;
    
    using System.Collections.Generic;
    
    using System.Web.Http.Dependencies;
    
    using Microsoft.Practices.Unity;
    
    namespace MyMvcAndWebApi.Helper
    
    {
    
        class ScopeContainer : IDependencyScope
    
        {
    
            protected IUnityContainer container;
    
            public ScopeContainer(IUnityContainer container)
    
            {
    
                if (container == null)
    
                {
    
                    throw new ArgumentNullException("container");
    
                }
    
                this.container = container;
    
            }
    
            public object GetService(Type serviceType)
    
            {
    
                if (container.IsRegistered(serviceType))
    
                {
    
                    return container.Resolve(serviceType);
    
                }
    
                else
    
                {
    
                    return null;
    
                }
    
            }
    
            public IEnumerable<object> GetServices(Type serviceType)
    
            {
    
                if (container.IsRegistered(serviceType))
    
                {
    
                    return container.ResolveAll(serviceType);
    
                }
    
                else
    
                {
    
                    return new List<object>();
    
                }
    
            }
    
            public void Dispose()
    
            {
    
                container.Dispose();
    
            }
    
        }
    
        class IoCContainer : ScopeContainer, IDependencyResolver
    
        {
    
            public IoCContainer(IUnityContainer container)
    
                : base(container)
    
            {
    
            }
    
            public IDependencyScope BeginScope()
    
            {
    
                var child = container.CreateChildContainer();
    
                return new ScopeContainer(child);
    
            }
    
        }
    
    }

    →在Global.asax中注册Unity。

    sing System.Web.Http;
    
    using System.Web.Mvc;
    
    using System.Web.Optimization;
    
    using System.Web.Routing;
    
    using Microsoft.Practices.Unity;
    
    using MyMvcAndWebApi.Controllers;
    
    using MyMvcAndWebApi.Helper;
    
    using MyMvcAndWebApi.Models;
    
    namespace MyMvcAndWebApi
    
    {
    
        // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
    
        // 请访问 http://go.microsoft.com/?LinkId=9394801
    
        public class WebApiApplication : System.Web.HttpApplication
    
        {
    
            //注册控制器,接口和实现
    
            void ConfigureApi(HttpConfiguration config)
    
            {
    
                var unity = new UnityContainer();
    
                unity.RegisterType<BooksController>();
    
                unity.RegisterType<IBookRepository, BookRepository>(new HierarchicalLifetimeManager());
    
                config.DependencyResolver = new IoCContainer(unity);
    
               
    
            }
    
            protected void Application_Start()
    
            {
    
                AreaRegistration.RegisterAllAreas();
    
                //注册依赖注入
    
                ConfigureApi(GlobalConfiguration.Configuration);
    
                WebApiConfig.Register(GlobalConfiguration.Configuration);
    
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    
                RouteConfig.RegisterRoutes(RouteTable.Routes);
    
                BundleConfig.RegisterBundles(BundleTable.Bundles);           
    
            }
    
        }
    
    }
    

     

    →创建一个空的Api控制器,编写如下:

    using System;
    
    using System.Collections.Generic;
    
    using System.Net;
    
    using System.Net.Http;
    
    using System.Web.Http;
    
    using MyMvcAndWebApi.Models;
    
    namespace MyMvcAndWebApi.Controllers
    
    {
    
        public class BooksController : ApiController
    
        {
    
            //_repository运行时变量,在首次引用IBookRepository方法时动态分配内存
    
            private static IBookRepository _repository;
    
            public BooksController(IBookRepository repository)
    
            {
    
                if (repository == null)
    
                {
    
                    throw new ArgumentNullException("repository");
    
                }
    
                _repository = repository;
    
            }
    
            //根据惯例,如果action名称以Get开头,那就接收Get请求
    
            public IEnumerable<Book> GetAllBooks()
    
            {
    
                return _repository.GetAll();
    
            }
    
            //ASP.NET Web API会自动帮我们把URL中的字符串id转换成参数类型int
    
            public Book GetBook(int id)
    
            {
    
                Book book = _repository.Get(id);
    
                if (book == null)
    
                {
    
                    //HttpResponseException封装返回的异常
    
                    //HttpResponseMessage封装返回的信息
    
                    throw new  HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
    
                }
    
                return book;
    
            }
    
            //添加
    
            //action名以post开头,按照惯例,接收post请求
    
            //客户端发送来序列化的Book对象,在服务端对Book对象反序列化
    
            public HttpResponseMessage PostBook(Book book)
    
            {
    
                book = _repository.Add(book);
    
                // Web API默认返回的状态码为200,可是,根据HTTP/1.1协议,在添加完,我们希望返回201状态码
    
                var response = Request.CreateResponse(HttpStatusCode.Created, book);
    
                //返回新创建资源的url
    
                string uri = Url.Route(null, new {id = book.Id});
    
                response.Headers.Location = new Uri(Request.RequestUri, uri);
    
                return response;
    
            }
    
            //修改
    
            //参数id从url中获取,book从request中反序列化
    
            //根据惯例,Put开头的action,接收put请求
    
            public void PutBook(int id, Book book)
    
            {
    
                book.Id = id;
    
                if (!_repository.Update(book))
    
                {
    
                    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
    
                }
    
            }
    
            //删除
    
            //根据管理,Delete开头接收delete请求
    
            public HttpResponseMessage DeleteBook(int id)
    
            {
    
                _repository.Remove(id);
    
                //返回200状态码表示删除成功
    
                //返回202状态码表示正在删除
    
                //返回204状态码表示没有内容
    
                return new HttpResponseMessage(HttpStatusCode.NoContent);
    
            }
    
        }
    
    }
    

    以上,所有action方法名称都符合了惯例。

     

    →修改Home/Index.cshtml,我们在此使用jquery与服务端api控制器进行交互。

    @section scripts {
    
        <script src="@Url.Content("~/Scripts/jquery-1.6.2.js")" type="text/javascript"> </script>
    
        <script src="@Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"> </script>
    
        <script src="@Url.Content("~/Scripts/jQuery.tmpl.js")" type="text/javascript"> </script>
    
        <script type="text/javascript">
    
            $(function () {
    
                //Get请求
    
                $.getJSON(
    
                    "api/books",
    
                    function (data) {
    
                        $.each(data,
    
                            function (index, value) {
    
                                $("#bookTemplate").tmpl(value).appendTo("#books");
    
                            }
    
                        );
    
                        $("#loader").hide("slow");
    
                        $("#addBook").show("slow");
    
                    }
    
                );
    
                //添加
    
                $("#addBook").submit(function () {
    
                    $.post(
    
                        "api/books",
    
                        $("#addBook").serialize(), //序列化Book对象
    
                        function (value) {
    
                            $("#bookTemplate").tmpl(value).appendTo("#books");
    
                            $("#name").val("");
    
                            $("#price").val("");
    
                        },
    
                        "json"
    
                    );
    
                    return false;
    
                });
    
                //删除
    
                $(".removeBook").live("click", function () {
    
                    $.ajax({
    
                        type: "DELETE",
    
                        url: $(this).attr("href"),
    
                        context: this,
    
                        success: function () {
    
                            $(this).closest("li").remove();
    
                        }
    
                    });
    
                    return false;
    
                });
    
                $("input[type="submit"], .removeBook, .viewImage").button();
    
            });
    
            //根据id搜索
    
            function find() {
    
                var id = $('#bookId').val();
    
                $.getJSON("api/books/" + id,
    
                    function (data) {
    
                        var str = data.Name + ': $' + data.Price;
    
                        $('#book').html(str);
    
                    })
    
                    .fail(
    
                        function (jqXHR, textStatus, err) {
    
                            $('#book').html('Error: ' + err);
    
                        });
    
            }
    
        </script>
    
        <script id="bookTemplate" type="text/html"> 
    
            <li>
    
                <p>
    
                    <strong> Book ID:</strong> ${ Id}
    
                    <br />
    
                    <strong> Book Name:</strong> ${ Name }
    
                    <br />
    
                    <strong> Price: $</strong> ${ Price }
    
                </p>
    
                <p>
    
                    <a href="${ Self }" class="button small red removeBook">移除</a>
    
                </p>
    
            </li>
    
        </script>
    
    }
    
    <body>
    
        <form method="post" id="addBook">
    
        <div class="container_16">
    
            <h1 class="title-01">Book信息</h1>
    
        </div>
    
        <div class="container_16">
    
            <div class="grid_16 body-container">
    
                <div class="margin grid_6 alpha">
    
                    <label for="Name">
    
                        Name</label><br />
    
                    <input type="text" id="name" name="Name" class="text grid_4" />
    
                    <br class="clear" />
    
                    <label for="Price">
    
                        Price</label><br />
    
                    <input type="text" id="price" name="Price" class="text grid_4" />
    
                    <br class="clear" />
    
                    <input type="submit" value="添加" class="button small green" />
    
                    <br />
    
                    <br />
    
                    <br class="clear" />
    
                    <strong id="book">@*   <label id="book">
    
                        </label>*@ </strong>
    
                    <br />
    
                    <br class="clear" />
    
                    <br />
    
                    <label for="bookId">
    
                        根据ID搜索
    
                    </label>
    
                    <br />
    
                    <input type="text" id="bookId" size="20" class="text grid_4" /><br class="clear" />
    
                    <input type="button" value="搜索" onclick="find();" class="button small gray" />
    
                </div>
    
                <div class="grid_8 omega">
    
                    <img id="loader" src="images/ajax-loader.gif" />
    
                    <ul id="books" class="books">
    
                    </ul>
    
                </div>
    
            </div>
    
        </div>
    
        <br class="clear" />
    
        <div class="footer clearfix">
    
        </div>
    
        </form>
    
    </body>
    


    另外,有关Bootsrap的样式在BundleConfig类中定义。

    参考资料:http://www.codeproject.com/Articles/344078/ASP-NET-WebAPI-Getting-Started-with-MVC-and-WebAP

  • 相关阅读:
    svmlight、libsvm 和 svmtorch(torch) 极夜.潜的日志 网易博客
    ObjectiveC学习之旅(二)函数、类、作用域
    快速掌握 ObjectiveC (For C/C++ developer)
    MAC系统使用总结
    VM虚拟机安装苹果雪豹操作系统
    asp.net调试遇到的问题
    C#调用WebService
    SqlServer2008建立触发器实例
    sqlserver2008无法登陆问题
    IIS上面部署网站
  • 原文地址:https://www.cnblogs.com/darrenji/p/4049555.html
Copyright © 2020-2023  润新知