美文网首页WEB前端程序开发程序员
翻译:ASP.NET MVC5使用WebAPI 2 和 Ang

翻译:ASP.NET MVC5使用WebAPI 2 和 Ang

作者: 凉风有兴 | 来源:发表于2017-06-16 21:10 被阅读1861次

    背景解释

    原文来自于https://www.codeproject.com/Tips/1074608/CRUD-in-ASP-NET-MVC-using-WebAPI-with-AngularJS

    代码DEMO:https://www.codeproject.com/KB/scripting/1074608/AngularJS_Demo.zip

    第一次翻译技术文章,感谢谷歌翻译~~

    CRUD是指在做计算处理时的增加(Create)、查询(Retrieve)(重新得到数据)、更新(Update)和删除(Delete)几个单词的首字母简写。主要被用在描述软件系统中数据库或者持久层的基本操作功能。

    这篇文章将帮助初学者在ASP.NET MVC 5中使用具有脚本语言的WebAPI 2 、AngularJS和MS SQL 2008R2数据库实现CRUD操作。

    介绍

    如您所知,AngularJS是单页应用程序开发中最流行的JavaScript框架之一。 您可以使用Angular进行插入,更新,删除和检索操作。 本文将演示如何使用Angular、MVC5和WebAPI2进行CRUD操作。 有经验的开发人员会发现这篇文章非常基本,是的,这篇文章是从初学者的角度写的,所以我尽量保持简洁易懂。

    开始代码

    让我们开始吧 !!!

    如下图在MSSQL中创建“TblProductList”表。

    在ASP.NET MVC 5中创建一个新项目,并根据需要命名并选择Empty项目模板。
    在添加文件夹和核心引用,勾选MVC和Web API选项:

    在这个项目中使用NuGet软件包管理器安装Entity Framework 6、Jquery和AngularJS。
    您还可以从官方网站下载jquery.js和angular.js,并将其粘贴到项目的“Scripts”文件夹中。

    右键单击“Model”文件夹,新建一个ADO.NET 实体数据模型 。 将其命名为“ProductDataContext.edmx”。

    选择“从数据库生成”,并根据SQL服务器配置连接字符串。

    生成模型后,您将获得TblProductList的实体。

    在根目录下创建新文件夹 Interface ,然后再新增一个类 IProductRepository.cs ,代码如下:

    interface IProductRepository
      {
          IEnumerable<TblProductList> GetAll();
          TblProductList Get(int id);
          TblProductList Add(TblProductList item);
          bool Update(TblProductList item);
          bool Delete(int id);
      }
    

    再次在根目录下新建文件夹 Repositories ,新建类ProductRepository.cs ,以此来实现使用 Entity Framework 进行数据库的创建,读取,更新,删除的操作方法。

    public class ProductRepository : IProductRepository
       {
           ProductDBEntities ProductDB = new ProductDBEntities();
    
           public IEnumerable<TblProductList> GetAll()
           {
               // TO DO : Code to get the list of all the records in database
               return ProductDB.TblProductLists;
           }
    
           public TblProductList Get(int id)
           {
               // TO DO : Code to find a record in database
               return ProductDB.TblProductLists.Find(id);
           }
    
           public TblProductList Add(TblProductList item)
           {
               if (item == null)
               {
                   throw new ArgumentNullException("item");
               }
    
               // TO DO : Code to save record into database
               ProductDB.TblProductLists.Add(item);
               ProductDB.SaveChanges();
               return item;
           }
    
           public bool Update(TblProductList item)
           {
               if (item == null)
               {
                   throw new ArgumentNullException("item");
               }
    
               // TO DO : Code to update record into database
               var products = ProductDB.TblProductLists.Single(a => a.Id == item.Id);
               products.Name = item.Name;
               products.Category = item.Category;
               products.Price = item.Price;
               ProductDB.SaveChanges();
    
               return true;
           }
    
           public bool Delete(int id)
           {
               // TO DO : Code to remove the records from database
               TblProductList products = ProductDB.TblProductLists.Find(id);
               ProductDB.TblProductLists.Remove(products);
               ProductDB.SaveChanges();
               return true;
           }
       }
    

    右键单击 Controllers 文件夹并添加新的Web API 2 控制器-空,取名为'ProductController.cs':

    public class ProductController : ApiController
       {
           static readonly IProductRepository repository = new ProductRepository();
    
           public IEnumerable GetAllProducts()
           {
               return repository.GetAll();
           }
    
           public TblProductList PostProduct(TblProductList item)
           {
               return repository.Add(item);
           }
    
           public IEnumerable PutProduct(int id, TblProductList product)
           {
               product.Id = id;
               if (repository.Update(product))
               {
                   return repository.GetAll();
               }
               else
               {
                   return null;
               }
           }
    
           public bool DeleteProduct(int id)
           {
               if (repository.Delete(id))
               {
                   return true;
               }
               else
               {
                   return false;
               }
           }
       }
    

    右键单击Controllers文件夹并添加新的控制器,取名为'HomeController.cs':

    public class HomeController : Controller
       {
           public ActionResult Product()
           {
               return View();
           }
       }
    

    右键单击ActionResult Product(),点击添加视图'Product.cshtml'。

    @{
        ViewBag.Title = "Products List";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    @section scripts {
    
        <link href="~/Content/CustomStyle.css" rel="stylesheet" />
        <script src="~/Scripts/jquery-1.10.2.min.js"></script>
        <script src="~/Scripts/angular.js"></script>
        <script src="~/Scripts/AngularDemo.js"></script>
    }
    <div ng-app="demoModule" id="body">
        <div ng-controller="demoCtrl">
            <h2>AngularJS CRUD Operations with MVC5 WebAPI</h2>
    
            <h3>List of Products</h3>
    
            <table ng-cloak>
                <thead>
                    <tr>
                        <th style="display: none;">ID</th>
                        <th>Name</th>
                        <th>Category</th>
                        <th>Price</th>
                        <th>Actions</th>
                    </tr>
                </thead>
                <tbody>
                    <tr ng-repeat="items in productsData">
                        <td hidden="hidden">{{items.Id}}</td>
                        <td>{{items.Name}}</td>
                        <td>{{items.Category}}</td>
                        <td>{{items.Price | currency:'&#8377;':2}}</td>
                        <td>
                       <button ng-model="$scope.Product" 
    
                       ng-click="edit(productsData[$index])">Edit</button>
                       <button ng-click="delete($index)">Delete</button>
                        </td>
                    </tr>
                </tbody>
                <tfoot>
                    <tr>
                        <td colspan="6">
                            <hr />
                        </td>
                    </tr>
                    <tr>
                        <td>Total :</td>
                        <td></td>
                        <td><label ng-bind="total() | 
                        currency:'&#8377;':2"></label></td>
                        <td></td>
                    </tr>
                </tfoot>
            </table>
            <br />
            <div style="border-top: solid 2px #282828; width: 430px; height: 10px"> </div>
    
            <div ng-show="Product.Id != '' ">
                <div>
                    <h2>Update Product</h2>
                </div>
                <div hidden="hidden">
                    <label for="id">Id</label>
                    <input type="text" data-ng-model="Product.Id" />
                </div>
                <div>
                    <label for="name">Name</label>
                    <input type="text" data-ng-model="Product.Name" />
                </div>
    
                <div>
                    <label for="category">Category</label>
                    <input type="text" data-ng-model="Product.Category" />
                </div>
    
                <div>
                    <label for="price">Price</label>
                    <input type="text" data-ng-model="Product.Price" />
                </div>
                <br />
                <div>
                    <button data-ng-click="update()">Update</button>
                    <button data-ng-click="cancel()">Cancel</button>
                </div>
            </div>
    
            <div ng-hide="Product.Id != '' ">
                <div>
                    <h2>Add New Product</h2>
                </div>
                <div>
                    <label for="name">Name</label>
                    <input type="text" data-ng-model="Product.Name" />
                </div>
    
                <div>
                    <label for="category">Category</label>
                    <input type="text" data-ng-model="Product.Category" />
                </div>
    
                <div>
                    <label for="price">Price</label>
                    <input type="text" data-ng-model="Product.Price" />
                </div>
                <br />
                <div>
                    <button data-ng-click="save()">Save</button>
                    <button data-ng-click="clear()">Clear</button>
                </div>
            </div>
        </div>
    </div>
    

    Scripts 文件夹中创建一个新的JavaScript文件“Angular Demo.js”,以使用角度代码实现CRUD操作。

    <span class="code-comment">//</span><span class="code-comment"> Defining angularjs module</span>
    <span class="code-keyword">var</span> app = angular.module(<span class="code-string">'</span><span class="code-string">demoModule'</span>, []);
    
    <span class="code-comment">//</span><span class="code-comment"> Defining angularjs Controller and injecting ProductsService</span>
    app.controller(<span class="code-string">'</span><span class="code-string">demoCtrl'</span>, <span class="code-keyword">function</span> ($scope, $http, ProductsService) {
    
        $scope.productsData = <span class="code-keyword">null</span>;
        <span class="code-comment">//</span><span class="code-comment"> Fetching records from the factory created at the bottom of the script file</span>
        ProductsService.GetAllRecords().then(<span class="code-keyword">function</span> (d) {
            $scope.productsData = d.data; <span class="code-comment">//</span><span class="code-comment"> Success</span>
        }, <span class="code-keyword">function</span> () {
            alert(<span class="code-string">'</span><span class="code-string">Error Occured !!!'</span>); <span class="code-comment">//</span><span class="code-comment"> Failed</span>
        });
    
        <span class="code-comment">//</span><span class="code-comment"> Calculate Total of Price After Initialization</span>
        $scope.total = <span class="code-keyword">function</span> () {
            <span class="code-keyword">var</span> total = <span class="code-digit">0</span>;
            angular.forEach($scope.productsData, <span class="code-keyword">function</span> (item) {
                total += item.Price;
            })
            <span class="code-keyword">return</span> total;
        }
    
        $scope.Product = {
            Id: <span class="code-string">'</span><span class="code-string">'</span>,
            Name: <span class="code-string">'</span><span class="code-string">'</span>,
            Price: <span class="code-string">'</span><span class="code-string">'</span>,
            Category: <span class="code-string">'</span><span class="code-string">'</span>
        };
    
        <span class="code-comment">//</span><span class="code-comment"> Reset product details</span>
        $scope.clear = <span class="code-keyword">function</span> () {
            $scope.Product.Id = <span class="code-string">'</span><span class="code-string">'</span>;
            $scope.Product.Name = <span class="code-string">'</span><span class="code-string">'</span>;
            $scope.Product.Price = <span class="code-string">'</span><span class="code-string">'</span>;
            $scope.Product.Category = <span class="code-string">'</span><span class="code-string">'</span>;
        }
    
        <span class="code-comment">//</span><span class="code-comment">Add New Item</span>
        $scope.save = <span class="code-keyword">function</span> () {
            <span class="code-keyword">if</span> ($scope.Product.Name != <span class="code-string">"</span><span class="code-string">"</span> &amp;&amp;
           $scope.Product.Price != <span class="code-string">"</span><span class="code-string">"</span> &amp;&amp; $scope.Product.Category != <span class="code-string">"</span><span class="code-string">"</span>) {
                <span class="code-comment">//</span><span class="code-comment"> Call Http request using $.ajax</span>
    
                <span class="code-comment">//</span><span class="code-comment">$.ajax({</span>
                <span class="code-comment">//</span><span class="code-comment">    type: 'POST',</span>
                <span class="code-comment">//</span><span class="code-comment">    contentType: 'application/json; charset=utf-8',</span>
                <span class="code-comment">//</span><span class="code-comment">    data: JSON.stringify($scope.Product),</span>
                <span class="code-comment">//</span><span class="code-comment">    url: 'api/Product/PostProduct',</span>
                <span class="code-comment">//</span><span class="code-comment">    success: function (data, status) {</span>
                <span class="code-comment">//</span><span class="code-comment">        $scope.$apply(function () {</span>
                <span class="code-comment">//</span><span class="code-comment">            $scope.productsData.push(data);</span>
                <span class="code-comment">//</span><span class="code-comment">            alert("Product Added Successfully !!!");</span>
                <span class="code-comment">//</span><span class="code-comment">            $scope.clear();</span>
                <span class="code-comment">//</span><span class="code-comment">        });</span>
                <span class="code-comment">//</span><span class="code-comment">    },</span>
                <span class="code-comment">//</span><span class="code-comment">    error: function (status) { }</span>
                <span class="code-comment">//</span><span class="code-comment">});</span>
    
                <span class="code-comment">//</span><span class="code-comment"> or you can call Http request using $http</span>
                $http({
                    method: <span class="code-string">'</span><span class="code-string">POST'</span>,
                    url: <span class="code-string">'</span><span class="code-string">api/Product/PostProduct/'</span>,
                    data: $scope.Product
                }).then(<span class="code-keyword">function</span> successCallback(response) {
                    <span class="code-comment">//</span><span class="code-comment"> this callback will be called asynchronously</span>
                    <span class="code-comment">//</span><span class="code-comment"> when the response is available</span>
                    $scope.productsData.push(response.data);
                    $scope.clear();
                    alert(<span class="code-string">"</span><span class="code-string">Product Added Successfully !!!"</span>);
                }, <span class="code-keyword">function</span> errorCallback(response) {
                    <span class="code-comment">//</span><span class="code-comment"> called asynchronously if an error occurs</span>
                    <span class="code-comment">//</span><span class="code-comment"> or server returns response with an error status.</span>
                    alert(<span class="code-string">"</span><span class="code-string">Error : "</span> + response.data.ExceptionMessage);
                });
            }
            <span class="code-keyword">else</span> {
                alert(<span class="code-string">'</span><span class="code-string">Please Enter All the Values !!'</span>);
            }
        };
    
        <span class="code-comment">//</span><span class="code-comment"> Edit product details</span>
        $scope.edit = <span class="code-keyword">function</span> (data) {
            $scope.Product = { Id: data.Id, Name: data.Name, Price: data.Price, Category: data.Category };
        }
    
        <span class="code-comment">//</span><span class="code-comment"> Cancel product details</span>
        $scope.cancel = <span class="code-keyword">function</span> () {
            $scope.clear();
        }
    
        <span class="code-comment">//</span><span class="code-comment"> Update product details</span>
        $scope.update = <span class="code-keyword">function</span> () {
            <span class="code-keyword">if</span> ($scope.Product.Name != <span class="code-string">"</span><span class="code-string">"</span> &amp;&amp;
           $scope.Product.Price != <span class="code-string">"</span><span class="code-string">"</span> &amp;&amp; $scope.Product.Category != <span class="code-string">"</span><span class="code-string">"</span>) {
                $http({
                    method: <span class="code-string">'</span><span class="code-string">PUT'</span>,
                    url: <span class="code-string">'</span><span class="code-string">api/Product/PutProduct/'</span> + $scope.Product.Id,
                    data: $scope.Product
                }).then(<span class="code-keyword">function</span> successCallback(response) {
                    $scope.productsData = response.data;
                    $scope.clear();
                    alert(<span class="code-string">"</span><span class="code-string">Product Updated Successfully !!!"</span>);
                }, <span class="code-keyword">function</span> errorCallback(response) {
                    alert(<span class="code-string">"</span><span class="code-string">Error : "</span> + response.data.ExceptionMessage);
                });
            }
            <span class="code-keyword">else</span> {
                alert(<span class="code-string">'</span><span class="code-string">Please Enter All the Values !!'</span>);
            }
        };
    
        <span class="code-comment">//</span><span class="code-comment"> Delete product details</span>
        $scope.<span class="code-keyword">delete</span> = <span class="code-keyword">function</span> (index) {
            $http({
                method: <span class="code-string">'</span><span class="code-string">DELETE'</span>,
                url: <span class="code-string">'</span><span class="code-string">api/Product/DeleteProduct/'</span> + $scope.productsData[index].Id,
            }).then(<span class="code-keyword">function</span> successCallback(response) {
                $scope.productsData.splice(index, <span class="code-digit">1</span>);
                alert(<span class="code-string">"</span><span class="code-string">Product Deleted Successfully !!!"</span>);
            }, <span class="code-keyword">function</span> errorCallback(response) {
                alert(<span class="code-string">"</span><span class="code-string">Error : "</span> + response.data.ExceptionMessage);
            });
        };
    
    });
    
    <span class="code-comment">//</span><span class="code-comment"> Here I have created a factory which is a popular way to create and configure services.</span>
    <span class="code-comment">//</span><span class="code-comment"> You may also create the factories in another script file which is best practice.</span>
    
    app.factory(<span class="code-string">'</span><span class="code-string">ProductsService'</span>, <span class="code-keyword">function</span> ($http) {
        <span class="code-keyword">var</span> fac = {};
        fac.GetAllRecords = <span class="code-keyword">function</span> () {
            <span class="code-keyword">return</span> $http.get(<span class="code-string">'</span><span class="code-string">api/Product/GetAllProducts'</span>);
        }
        <span class="code-keyword">return</span> fac;
    });
    

    注意

    您可以使用jQuery中的$.ajax或来自angular.js的$http来进行HTTP请求。

    但是最好就是使用angular.js的$http,因为使用$.ajax 会迫使我们使用$scope.apply,如果您使用$ http不需要。

    您也可以使用 $resource ,这被认为是在RESTful Web API中进行CRUD操作的最佳做法。 本教程适用于初学者,所以我试图通过使用$http 来保持简单。

    基于架构的关系,而不是控制器,您可以在我们的自定义工厂中调用$http请求POST,PUT,DELETE,就像我已经为$http.get()所做的那样,以便我们的控制器看起来很干净,并展现出适当的关注点分离。

    译者注:(关注点分离(Separation of concerns,SOC)是对只与“特定概念、目标”(关注点)相关联的软件组成部分进行“标识、封装和操纵”的能力,即标识、封装和操纵关注点的能力。是处理复杂性的一个原则。由于关注点混杂在一起会导致复杂性大大增加,所以能够把不同的关注点分离开来,分别处理就是处理复杂性的一个原则,一种方法。)

    现在,添加一个布局视图: '_Layout.cshtml'。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>@ViewBag.Title</title>
        <meta name="viewport" content="width=device-width" />
    </head>
    <body>
        <div id="body">
            @RenderSection("featured", required: false)
            <section class="content-wrapper main-content clear-fix">
                @RenderBody()
            </section>
        </div>
    
        @RenderSection("scripts", required: false)
    </body>
    </html>
    

    增加样式表'CustomStyle.css'以改善页面的外观和美感。

    [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
        display: none !important;
    }
    
    body {
                margin: 20px;
                font-family: "Arial", "Helventica", sans-serif;
            }
    
            label {
                width: 80px;
                display: inline-block;
            }
    
            button {
                display: inline-block;
                outline: none;
                cursor: pointer;
                text-align: center;
                text-decoration: none;
                padding: .4em 1.1em .4em;
                color: #fef4e9;
                border: solid 1px #006fb9;
                background: #1276bb;
            }
    
                button:hover {
                    text-decoration: none;
                    background: #282828;
                    border: solid 1px #000;
                }
    
            table {
                padding-top: 1em;
            }
    
            thead, tfoot {
                font-weight: 600;
            }
    
            th, td {
                padding: .1em .5em;
                text-align: left;
            }
    
                td li, td ul {
                    margin: 0;
                    padding: 0;
                }
    
                td li {
                    display: inline;
                }
    
                    td li::after {
                        content: ',';
                    }
    
                    td li:last-child::after {
                        content: '';
                    }
    

    注意

    在这里,我已经根据 AngularJS文档 定义了在我们的“Product.cshtml”中使用的ng-cloak指令的样式。<br class="Apple-interchange-newline"><div id="inner-editor"></div>

    ngCloak指令用于防止在加载应用程序时浏览器以原始(未编译)形式简要显示Angular HTML模板。 使用此指令可避免HTML模板显示引起的不希望的闪烁效应。

    相关文章

      网友评论

        本文标题: 翻译:ASP.NET MVC5使用WebAPI 2 和 Ang

        本文链接:https://www.haomeiwen.com/subject/ujgmqxtx.html