在 Angular 和 .Net MVC 5 / Web API 中使用 http.delete
Using http.delete in Angular and .Net MVC 5 / Web API
使用 WebApi 和 MVC 5 和
AngularJS v1.3.4
我有一个 API 设置,其中包含 FavoritesRepository
& IFavoritesRepository
& Ninject。这部分没问题,我可以通过 UserId 或 SearchId 检索收藏夹。我的收藏夹列表是 API 围绕 Search.cs
模型构建的:
namespace RenderLib.Models
{
public class Search
{
public int SearchId { get; set; }
[MaxLength(128), Column(TypeName = "nvarchar")]
public string UserId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime? Created { get; set; }
[MaxLength(2080), Column(TypeName = "nvarchar")]
public string SearchString { get; set; }
}
}
在我的 DataLayer 目录中,我有 FavoritesRepository
& IFavoritesRepository
以及以下添加和删除方法。
(Add 方法适用于 Angular 就好了):
/DataLayer/IFavoritesRepository.cs
namespace RenderLib.DataLayer
{
public interface IFavoritesRepository
{
IQueryable<Search> GetFavoritesByUserId(string id);
IQueryable<Search> GetFavoriteBySearchId(int id);
bool Save();
bool AddFavorite(Search newSearch);
bool DelFavorite(int id);
}
}
/DataLayer/FavoritesRepository.cs
namespace RenderLib.DataLayer
{
public class FavoritesRepository : IFavoritesRepository
{
RenderLibContext _ctx;
public FavoritesRepository(RenderLibContext ctx)
{
_ctx = ctx;
}
public IQueryable<Search> GetFavoritesByUserId(string id)
{
return _ctx.Search.Where(s => s.UserId == id);
}
public IQueryable<Search> GetFavoriteBySearchId(int id)
{
return _ctx.Search.Where(s => s.SearchId == id);
}
public bool Save()
{
try
{
return _ctx.SaveChanges() > 0;
}
catch
{
// TODO log this error
return false;
}
}
public bool AddFavorite(Search newFavorite)
{
_ctx.Search.Add(newFavorite);
return true;
}
public bool DelFavorite(int id)
{
var search = _ctx.Search;
search.Remove(search.SingleOrDefault(s => s.SearchId == id));
return true;
}
}
}
我有一个 WebAPI 控制器,其中 POST 方法已经添加了一个新的收藏夹。我已经复制了 POST 并将其更改为 delete 并试图让它工作,但我真正的问题是弄清楚如何处理 Angular
/Controllers/Api/FavoritesController.cs
public class FavoritesController : ApiController
{
private IFavoritesRepository _favRepo;
public FavoritesController(IFavoritesRepository favRepo)
{
_favRepo = favRepo;
}
public IEnumerable<Search> Get()
{
var id = User.Identity.GetUserId();
IQueryable<Search> results;
results = _favRepo.GetFavoritesByUserId(id);
var favorites = results.OrderByDescending(s => s.UserId == id);
return favorites;
}
public HttpResponseMessage Post([FromBody]Search newFavorite)
{
if (newFavorite.Created == null)
{
newFavorite.Created = DateTime.UtcNow;
}
if (_favRepo.AddFavorite(newFavorite) && _favRepo.Save())
{
return Request.CreateResponse(HttpStatusCode.Created, newFavorite);
}
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
public HttpResponseMessage Delete(Search id)
{
if (_favRepo.DelFavorite(id) && _favRepo.Save())
{
return Request.CreateResponse(HttpStatusCode.Created, id);
}
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
在 Angular 端,我们有 Index.cshtml 页面,该页面是站点的根目录,其中包含一段 angular 代码。该部分有两条 angular 路线,一条 "#/"
加载以下 angular template/view:favoritesView.html
& newFavoiteView.html
其中有 angular 路线 "#/newfavorite"
/ng-templates/favoritesView.html
路线:#/
<a class="tiny button radius" href="#/newfavorite">Add</div>
<div class="small-12 column">
<div class="favContent">
<div class="search row" data-ng-repeat="s in vm.searches">
<div class="favName small-10 column">
<a href="{{s.searchString}}">{{s.name}}</a>
</div>
<div class="small-2 column">
<a href="" ng-click="vm.delete(s.searchId)">
<i class="fi-trash"></i>
</a>
</div>
</div>
</div>
</div>
/ng-templates/newFavoriteView.html
路线:#/newfavorite
<div class="small-12 column"><h3>Saving Search</h3></div>
<div class="small-12 column">
<form name="newFavoriteForm" novalidate ng-submit="vm.save()">
<input name="userId" type="hidden"
ng-model="vm.newFavorite.userId" />
<input name="searchString" type="hidden"
ng-model="vm.newFavorite.searchString" />
<label for="name">Name</label>
<input name="name" type="text"
ng-model="vm.newFavorite.name" autofocus/>
<label for="description">Description</label>
<textarea name="description" rows="5" cols="30"
ng-model="vm.newFavorite.description"></textarea>
<input type="submit" class="tiny button radius" value="Save" /> |
<a href="#/" class="tiny button radius">Cancel</a>
</form>
</div>
我终于有了 Angular 模块和控制器(同样,除删除外一切正常。我只是不确定我应该在我的 favoritesView.html 中做什么以及它是如何工作的使用控制器。我的 WebApi 控制器和 Repo 设置是否正确?
模块和控制器
/ng-modules/render-index.js
angular
.module("renderIndex", ["ngRoute","ngCookies"])
.config(config)
.controller("favoritesController", favoritesController)
.controller("newFavoriteController", newFavoriteController);
function config($routeProvider) {
$routeProvider
.when("/", {
templateUrl: "/ng-templates/favoritesView.html",
controller: "favoritesController",
controllerAs: "vm"
})
.when("/newfavorite", {
templateUrl: "/ng-templates/newFavoriteView.html",
controller: "newFavoriteController",
controllerAs: "vm"
})
.otherwise({ redirectTo: "/" });
};
function favoritesController($http) {
var vm = this;
vm.searches = [];
vm.isBusy = true;
$http.get("/api/favorites")
.success(function (result) {
vm.searches = result;
})
.error(function () {
alert('error/failed');
})
.then(function () {
vm.isBusy = false;
});
vm.delete = function (searchId) {
var url = "/api/favorites/" + searchId;
$http.delete(url)
.success(function (result) {
var newFavorite = result.data;
//TODO: merge with existing topics
alert("Delete Successfull");
removeFromArray(vm.searches, searchId);
})
.error(function () {
alert("Your broken, go fix yourself!");
})
.then(function () {
$window.location = "#/";
});
};
};
function removeFromArray(items, searchId) {
var index;
for (var i = 0; i < items.length; i++) {
if (items[i].searchId == searchId) {
index = i;
break;
}
}
if (index) {
items.splice(index, 1);
}
}
function newFavoriteController($http, $window, $cookies) {
var vm = this;
vm.newFavorite = {};
vm.newFavorite.searchString = $cookies.currentSearch;
vm.newFavorite.userId = $cookies.uId;
vm.save = function () {
$http.post("/api/favorites", vm.newFavorite)
.success(function (result) {
var newFavorite = result.data;
//TODO: merge with existing topics
alert("Thanks for your post");
})
.error(function () {
alert("Your broken, go fix yourself!");
})
.then(function () {
$window.location = "#/";
});
};
};
我想了一个晚上。此代码来自 Shawn Wildermuth 的 plurarisight 视频,我将其更改为与 ControllerAs
一起使用并摆脱了范围,出于某种原因我只是不知道如何设置删除。任何帮助或朝着正确方向的推动将不胜感激。到目前为止,我不能让删除操作打败我。
回答
上面的代码已经用工作版本更新了。我们的想法是删除 favoritesView.html
上的表格,只使用
<a href="javascript:void(0);" ng-click="vm.delete(s.searchId)">X</a>
调用删除函数。 Omri 不仅帮助我了解了如何将参数传递给函数的概念,还帮助我编写了一个函数来更新视图以显示已删除的项目。我非常感谢他的帮助。如果您觉得有用,请把他的回答顶起来。
我将总结为一个答案,因为评论太忙了:)
因为视图中有 ng-model="vm.newFavorite.searchId"
,您可以获得 searchId 并使用它附加到 url:
vm.delete = function (searchId) {
//API Controller will expect "/api/favorites/13" from an http delete
var url = "/api/favorites/" + searchId;
$http.delete(url)
.success(function (result) {
var newFavorite = result.data;
//TODO: merge with existing topics
alert("Delete Successfull");
removeFromArray(vm.searches, searchId);
})
.error(function () {
alert("Your broken, go fix yourself!");
})
.then(function () {
$window.location = "#/";
});
};
};
请注意,现在 FavoritesController
中的 Delete
函数现在只需要一个 searchId
参数,因此您需要更改客户端或服务器上的名称,以便它们应该匹配,并且您肯定需要将服务器中变量的类型从 Search
更改为我假设的字符串或 Guid。
编辑:经过聊天讨论,我们得出的结论是删除表单元素,只有一个按钮和ng-click
删除功能。
使用 WebApi 和 MVC 5 和
AngularJS v1.3.4
我有一个 API 设置,其中包含 FavoritesRepository
& IFavoritesRepository
& Ninject。这部分没问题,我可以通过 UserId 或 SearchId 检索收藏夹。我的收藏夹列表是 API 围绕 Search.cs
模型构建的:
namespace RenderLib.Models
{
public class Search
{
public int SearchId { get; set; }
[MaxLength(128), Column(TypeName = "nvarchar")]
public string UserId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime? Created { get; set; }
[MaxLength(2080), Column(TypeName = "nvarchar")]
public string SearchString { get; set; }
}
}
在我的 DataLayer 目录中,我有 FavoritesRepository
& IFavoritesRepository
以及以下添加和删除方法。
(Add 方法适用于 Angular 就好了):
/DataLayer/IFavoritesRepository.cs
namespace RenderLib.DataLayer
{
public interface IFavoritesRepository
{
IQueryable<Search> GetFavoritesByUserId(string id);
IQueryable<Search> GetFavoriteBySearchId(int id);
bool Save();
bool AddFavorite(Search newSearch);
bool DelFavorite(int id);
}
}
/DataLayer/FavoritesRepository.cs
namespace RenderLib.DataLayer
{
public class FavoritesRepository : IFavoritesRepository
{
RenderLibContext _ctx;
public FavoritesRepository(RenderLibContext ctx)
{
_ctx = ctx;
}
public IQueryable<Search> GetFavoritesByUserId(string id)
{
return _ctx.Search.Where(s => s.UserId == id);
}
public IQueryable<Search> GetFavoriteBySearchId(int id)
{
return _ctx.Search.Where(s => s.SearchId == id);
}
public bool Save()
{
try
{
return _ctx.SaveChanges() > 0;
}
catch
{
// TODO log this error
return false;
}
}
public bool AddFavorite(Search newFavorite)
{
_ctx.Search.Add(newFavorite);
return true;
}
public bool DelFavorite(int id)
{
var search = _ctx.Search;
search.Remove(search.SingleOrDefault(s => s.SearchId == id));
return true;
}
}
}
我有一个 WebAPI 控制器,其中 POST 方法已经添加了一个新的收藏夹。我已经复制了 POST 并将其更改为 delete 并试图让它工作,但我真正的问题是弄清楚如何处理 Angular
/Controllers/Api/FavoritesController.cs
public class FavoritesController : ApiController
{
private IFavoritesRepository _favRepo;
public FavoritesController(IFavoritesRepository favRepo)
{
_favRepo = favRepo;
}
public IEnumerable<Search> Get()
{
var id = User.Identity.GetUserId();
IQueryable<Search> results;
results = _favRepo.GetFavoritesByUserId(id);
var favorites = results.OrderByDescending(s => s.UserId == id);
return favorites;
}
public HttpResponseMessage Post([FromBody]Search newFavorite)
{
if (newFavorite.Created == null)
{
newFavorite.Created = DateTime.UtcNow;
}
if (_favRepo.AddFavorite(newFavorite) && _favRepo.Save())
{
return Request.CreateResponse(HttpStatusCode.Created, newFavorite);
}
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
public HttpResponseMessage Delete(Search id)
{
if (_favRepo.DelFavorite(id) && _favRepo.Save())
{
return Request.CreateResponse(HttpStatusCode.Created, id);
}
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
在 Angular 端,我们有 Index.cshtml 页面,该页面是站点的根目录,其中包含一段 angular 代码。该部分有两条 angular 路线,一条 "#/"
加载以下 angular template/view:favoritesView.html
& newFavoiteView.html
其中有 angular 路线 "#/newfavorite"
/ng-templates/favoritesView.html
路线:#/
<a class="tiny button radius" href="#/newfavorite">Add</div>
<div class="small-12 column">
<div class="favContent">
<div class="search row" data-ng-repeat="s in vm.searches">
<div class="favName small-10 column">
<a href="{{s.searchString}}">{{s.name}}</a>
</div>
<div class="small-2 column">
<a href="" ng-click="vm.delete(s.searchId)">
<i class="fi-trash"></i>
</a>
</div>
</div>
</div>
</div>
/ng-templates/newFavoriteView.html
路线:#/newfavorite
<div class="small-12 column"><h3>Saving Search</h3></div>
<div class="small-12 column">
<form name="newFavoriteForm" novalidate ng-submit="vm.save()">
<input name="userId" type="hidden"
ng-model="vm.newFavorite.userId" />
<input name="searchString" type="hidden"
ng-model="vm.newFavorite.searchString" />
<label for="name">Name</label>
<input name="name" type="text"
ng-model="vm.newFavorite.name" autofocus/>
<label for="description">Description</label>
<textarea name="description" rows="5" cols="30"
ng-model="vm.newFavorite.description"></textarea>
<input type="submit" class="tiny button radius" value="Save" /> |
<a href="#/" class="tiny button radius">Cancel</a>
</form>
</div>
我终于有了 Angular 模块和控制器(同样,除删除外一切正常。我只是不确定我应该在我的 favoritesView.html 中做什么以及它是如何工作的使用控制器。我的 WebApi 控制器和 Repo 设置是否正确?
模块和控制器 /ng-modules/render-index.js
angular
.module("renderIndex", ["ngRoute","ngCookies"])
.config(config)
.controller("favoritesController", favoritesController)
.controller("newFavoriteController", newFavoriteController);
function config($routeProvider) {
$routeProvider
.when("/", {
templateUrl: "/ng-templates/favoritesView.html",
controller: "favoritesController",
controllerAs: "vm"
})
.when("/newfavorite", {
templateUrl: "/ng-templates/newFavoriteView.html",
controller: "newFavoriteController",
controllerAs: "vm"
})
.otherwise({ redirectTo: "/" });
};
function favoritesController($http) {
var vm = this;
vm.searches = [];
vm.isBusy = true;
$http.get("/api/favorites")
.success(function (result) {
vm.searches = result;
})
.error(function () {
alert('error/failed');
})
.then(function () {
vm.isBusy = false;
});
vm.delete = function (searchId) {
var url = "/api/favorites/" + searchId;
$http.delete(url)
.success(function (result) {
var newFavorite = result.data;
//TODO: merge with existing topics
alert("Delete Successfull");
removeFromArray(vm.searches, searchId);
})
.error(function () {
alert("Your broken, go fix yourself!");
})
.then(function () {
$window.location = "#/";
});
};
};
function removeFromArray(items, searchId) {
var index;
for (var i = 0; i < items.length; i++) {
if (items[i].searchId == searchId) {
index = i;
break;
}
}
if (index) {
items.splice(index, 1);
}
}
function newFavoriteController($http, $window, $cookies) {
var vm = this;
vm.newFavorite = {};
vm.newFavorite.searchString = $cookies.currentSearch;
vm.newFavorite.userId = $cookies.uId;
vm.save = function () {
$http.post("/api/favorites", vm.newFavorite)
.success(function (result) {
var newFavorite = result.data;
//TODO: merge with existing topics
alert("Thanks for your post");
})
.error(function () {
alert("Your broken, go fix yourself!");
})
.then(function () {
$window.location = "#/";
});
};
};
我想了一个晚上。此代码来自 Shawn Wildermuth 的 plurarisight 视频,我将其更改为与 ControllerAs
一起使用并摆脱了范围,出于某种原因我只是不知道如何设置删除。任何帮助或朝着正确方向的推动将不胜感激。到目前为止,我不能让删除操作打败我。
回答
上面的代码已经用工作版本更新了。我们的想法是删除 favoritesView.html
上的表格,只使用
<a href="javascript:void(0);" ng-click="vm.delete(s.searchId)">X</a>
调用删除函数。 Omri 不仅帮助我了解了如何将参数传递给函数的概念,还帮助我编写了一个函数来更新视图以显示已删除的项目。我非常感谢他的帮助。如果您觉得有用,请把他的回答顶起来。
我将总结为一个答案,因为评论太忙了:)
因为视图中有 ng-model="vm.newFavorite.searchId"
,您可以获得 searchId 并使用它附加到 url:
vm.delete = function (searchId) {
//API Controller will expect "/api/favorites/13" from an http delete
var url = "/api/favorites/" + searchId;
$http.delete(url)
.success(function (result) {
var newFavorite = result.data;
//TODO: merge with existing topics
alert("Delete Successfull");
removeFromArray(vm.searches, searchId);
})
.error(function () {
alert("Your broken, go fix yourself!");
})
.then(function () {
$window.location = "#/";
});
};
};
请注意,现在 FavoritesController
中的 Delete
函数现在只需要一个 searchId
参数,因此您需要更改客户端或服务器上的名称,以便它们应该匹配,并且您肯定需要将服务器中变量的类型从 Search
更改为我假设的字符串或 Guid。
编辑:经过聊天讨论,我们得出的结论是删除表单元素,只有一个按钮和ng-click
删除功能。