WEB前端程序开发程序员

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

2017-06-16  本文已影响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模板显示引起的不希望的闪烁效应。

上一篇下一篇

猜你喜欢

热点阅读