我正在使用angularJS和Web Api构建小型网络应用程序。我在邮递员测试的同时创建了后端,一切正常。但是现在我不能让它从我的前端工作,至少不能用于POST; PUT和DELETE方法。 我已经尝试了一切,不过我有点绝望。
这是我的控制器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using PlaylistWebApi.Models;
using PlaylistWebApi.Services;
namespace PlaylistWebApi.Controllers
{
public class SongsController : ApiController
{
private readonly ISongService _service;
public SongsController(ISongService service)
{
_service = service;
}
public IEnumerable<Song> Get()
{
IEnumerable<Song> items = null;
try
{
items = _service.GetAll();
}
catch (Exception)
{
var message = string.Format("Error while retrieving songs!");
throw new HttpResponseException(
Request.CreateErrorResponse(HttpStatusCode.InternalServerError, message));
}
return items;
}
public Song Get(int id)
{
Song item = null;
try
{
item = _service.Get(id);
}
catch (Exception)
{
var message = string.Format("Error while retrieving the song!");
throw new HttpResponseException(
Request.CreateErrorResponse(HttpStatusCode.InternalServerError, message));
}
if (item == null)
{
var message = string.Format("Error while retriving song!");
throw new HttpResponseException(
Request.CreateErrorResponse(HttpStatusCode.NotFound, message));
}
else
{
return item;
}
}
[AllowAnonymous]
[HttpOptions,HttpPost]
public Song Post([FromBody]Song song)
{
Song item = null;
try
{
item = _service.Add(song);
}
catch (Exception)
{
var message = string.Format("Error while adding new song!");
throw new HttpResponseException(
Request.CreateErrorResponse(HttpStatusCode.InternalServerError, message));
}
return item;
}
[AllowAnonymous]
[HttpOptions,HttpPut]
public void Put(int id, [FromBody]Song item)
{
try
{
_service.Update(item);
}
catch (Exception)
{
var message = string.Format("Error while editing song!");
throw new HttpResponseException(
Request.CreateErrorResponse(HttpStatusCode.InternalServerError, message));
}
}
[AllowAnonymous]
[HttpOptions,HttpDelete]
public void Delete(int id)
{
try
{
_service.Remove(id);
}
catch (Exception)
{
var message = string.Format("Error while removing song!");
throw new HttpResponseException(
Request.CreateErrorResponse(HttpStatusCode.InternalServerError, message));
}
}
}
}
这是我的前置回调
playlistService.service('dataService', ['$http', function ($http) {
var urlBase = 'http://localhost:9000/api';
this.getSongs= function () {
return $http.get(urlBase+ '/songs');
};
this.getSong = function (id) {
return $http.get(urlBase + '/songs/' + id);
};
this.insertSong = function (song) {
return $http.post(urlBase+ '/songs/', song);
};
this.updateSong = function (song) {
return $http.put(urlBase+'/songs/'+ song.ID , song);
};
this.deleteSong = function (id) {
return $http.delete(urlBase + '/songs/' + id);
};
}]);
删除方法错误
Remote Address:[::1]:9000
Request URL:http: //localhost:9000/api/songs/5
Request Method:OPTIONS
Status Code:500 Internal Server Error
Response Headers
view source
Access-Control-Allow-Headers:*
Access-Control-Allow-Methods:*
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Content-Length:2236
Content-Type:application/json; charset=utf-8
Date:Fri, 03 Jul 2015 00:22:25 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.0
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?RDpccmVwb3NpdG9yeVxQbGF5bGlzdFdlYkFwaVxQbGF5bGlzdFdlYkFwaVxhcGlcc29uZ3NcNQ==?=
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept
Access-Control-Request-Method:DELETE
Connection:keep-alive
Host:localhost:9000
Origin:http: //127.0.0.1:50119
Referer:http: //127.0.0.1:50119/index.html
Operation=ApiControllerActionSelector.SelectAction, Exception=System.InvalidOperationException: Multiple actions were found that match the request:
Put on type PlaylistWebApi.Controllers.SongsController
delete on type PlaylistWebApi.Controllers.SongsController
at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)
at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)
at System.Web.Http.Tracing.Tracers.HttpActionSelectorTracer.<>c__DisplayClass2.<System.Web.Http.Controllers.IHttpActionSelector.SelectAction>b__0()
at System.Web.Http.Tracing.ITraceWriterExtensions.TraceBeginEnd(ITraceWriter traceWriter, HttpRequestMessage request, String category, TraceLevel level, String operatorName, String operationName, Action`1 beginTrace, Action execute, Action`1 endTrace, Action`1 errorTrace)
iisexpress.exe Error: 0 : Operation=SongsController.ExecuteAsync, Exception=System.InvalidOperationException: Multiple actions were found that match the request:
Put on type PlaylistWebApi.Controllers.SongsController
delete on type PlaylistWebApi.Controllers.SongsController
at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)
at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)
at System.Web.Http.Tracing.Tracers.HttpActionSelectorTracer.<>c__DisplayClass2.<System.Web.Http.Controllers.IHttpActionSelector.SelectAction>b__0()
at System.Web.Http.Tracing.ITraceWriterExtensions.TraceBeginEnd(ITraceWriter traceWriter, HttpRequestMessage request, String category, TraceLevel level, String operatorName, String operationName, Action`1 beginTrace, Action execute, Action`1 endTrace, Action`1 errorTrace)
at System.Web.Http.Tracing.Tracers.HttpActionSelectorTracer.System.Web.Http.Controllers.IHttpActionSelector.SelectAction(HttpControllerContext controllerContext)
at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
at System.Web.Http.Tracing.Tracers.HttpControllerTracer.<ExecuteAsyncCore>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext()
iisexpress.exe Information: 0 : Message='Will use same 'JsonMediaTypeFormatter' formatter', Operation=JsonMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Selected formatter='JsonMediaTypeFormatter', content-type='application/json; charset=utf-8'', Operation=DefaultContentNegotiator.Negotiate
iisexpress.exe Information: 0 : Response, Status=500 (InternalServerError), Method=OPTIONS, Url=http: //localhost:9000/api/songs/5, Message='Content-type='application/json; charset=utf-8', content-length=unknown'
iisexpress.exe Information: 0 : Operation=JsonMediaTypeFormatter.WriteToStreamAsync
iisexpress.exe Information: 0 : Operation=SongsController.Dispose
对于POST,PUT我没有收到任何错误,它将我重新定向回来与奇怪的uri(我发布的对象)相同。我做错了什么?
<div class="row">
<div class="col-lg-12">
<h3 class="page-header"><i class="fa fa-plus "></i> Songs</h3>
<ol class="breadcrumb">
<li><i class="fa fa-home"></i><a href="#">Home</a></li>
<li><i class="icon_mic_alt"></i>Songs</li>
<li><i class="fa fa-plus "></i>Add New</li>
</ol>
</div>
</div>
<!-- Form validations -->
<div class="row">
<div class="col-lg-12">
<section class="panel">
<header class="panel-heading">
Add New Song
</header>
<div class="panel-body">
<form class="form-validate form-horizontal " id="register_form" method="get" action="">
<div class="alert alert-block" >
<div ng-repeat="alert in alerts" type="{{alert.type}}" close="closeAlert($index)">
<button data-dismiss="alert" class="close close-sm" type="button" >{{alert.msg}}>
<i class="icon-remove"></i>
</button>
</div>
</div>
<div class="form-group">
<label for="songname" class="control-label col-lg-2">Song name <span class="required">*</span></label>
<div class="col-lg-10">
<input class="form-control" id="songname" name="songname" ng-model="songName" type="text" />
</div>
</div>
<div class="form-group">
<label for="filename" class="control-label col-lg-2">File Name <span class="required">*</span></label>
<div class="col-lg-10">
<input class="form-control" id="filename" name="filename" ng-model="fileName" type="text" />
</div>
</div>
<div class="form-group">
<label for="artistname" class="control-label col-lg-2">Username <span class="required">*</span></label>
<div class="col-lg-10">
<input class="form-control" id="artistname" name="artistname" ng-model="artistName" type="text" />
</div>
</div>
<div class="form-group">
<label for="album" class="control-label col-lg-2">Album</label>
<div class="col-lg-10">
<input class="form-control" id="album" name="album" ng-model="album" type="text" />
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<button class="btn btn-primary" ng-click="addSong()">Save</button>
</div>
</div>
</form>
</div>
</section>
</div>
</div>
答案 0 :(得分:0)
这里有几个问题。首先,OPTIONS请求有例外。
Multiple actions were found that match the request:
Put on type PlaylistWebApi.Controllers.SongsController
delete on type PlaylistWebApi.Controllers.SongsController
从其他操作中删除HttpOptions
并创建专用端点。
[HttpOptions]
public HttpResponseMessage Options()
{
return new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
}
接下来,您将重定向回到具有奇怪URL的表单,表明您可能已经允许标准表单提交。 Angular将为您解决此问题 - 只需删除action
参数并指定ng-submit
即可。不要忘记从按钮中删除ng-click
。
<form id="register_form" ng-submit="addSong()">
<button type="submit" class="btn btn-primary">Save</button>
</form>
来自ngSubmit:
启用将角度表达式绑定到onsubmit事件。
此外,它会阻止默认操作(表单意味着将请求发送到服务器并重新加载当前页面),但前提是表单不包含操作,数据操作或x-action属性。