我在控制器上的所有操作上都有属性路由(尽管定义了默认的常规路由)。我(我认为)尝试过是否使用[HttpPost]和是否使用[FromBody]的每种组合。
如果我尝试仅使用定义了控制器名称的属性...
[HttpPost]
[Route("Relationships")]
private async Task<IHttpActionResult> PostRelationship([FromBody]Relationship relationship)
Request URL:http://localhost:51599/api/Relationships
Request method:POST
...我得到405。
似乎正在使用属性路由-调试GetRouteData()显示了一个子路由,该子路由已解析为“ GetController”操作。
subroutes {System.Web.Http.Routing.IHttpRouteData[1]} System.Collections.Generic.IEnumerable<System.Web.Http.Routing.IHttpRouteData> {System.Web.Http.Routing.IHttpRouteData[]}
- [0] {System.Web.Http.Routing.HttpRouteData} System.Web.Http.Routing.IHttpRouteData {System.Web.Http.Routing.HttpRouteData}
- Route {System.Web.Http.Routing.HttpRoute} System.Web.Http.Routing.IHttpRoute {System.Web.Http.Routing.HttpRoute}
+ Constraints Count = 0 System.Collections.Generic.IDictionary<string, object> {System.Web.Http.Routing.HttpRouteValueDictionary}
- DataTokens Count = 2 System.Collections.Generic.IDictionary<string, object> {System.Web.Http.Routing.HttpRouteValueDictionary}
- [0] {[actions, System.Web.Http.Controllers.HttpActionDescriptor[]]} System.Collections.Generic.KeyValuePair<string, object>
Key "actions" string
- Value {System.Web.Http.Controllers.HttpActionDescriptor[1]} object {System.Web.Http.Controllers.HttpActionDescriptor[]}
- [0] {System.Web.Http.Controllers.ReflectedHttpActionDescriptor} System.Web.Http.Controllers.HttpActionDescriptor {System.Web.Http.Controllers.ReflectedHttpActionDescriptor}
+ ActionBinding {System.Web.Http.Controllers.HttpActionBinding} System.Web.Http.Controllers.HttpActionBinding
ActionName "GetRelationships" string
如果我尝试使用操作名称作为路线...
[HttpPost]
[Route("Relationships/PostRelationship")]
private async Task<IHttpActionResult> PostRelationship([FromBody]Relationship relationship)
http://localhost:51599/api/Relationships/PostRelationship
Request method:POST
...我得到404。
在这种情况下,它似乎陷入了默认的控制器-调试GetRouteData()表明它认为我正在提供“控制器”和“ id”。
routeData {System.Web.Routing.RouteData} System.Web.Routing.RouteData
+ DataTokens {System.Web.Routing.RouteValueDictionary} System.Web.Routing.RouteValueDictionary
+ Route {System.Web.Http.WebHost.Routing.HttpWebRoute} System.Web.Routing.RouteBase {System.Web.Http.WebHost.Routing.HttpWebRoute}
+ RouteHandler {System.Web.Http.WebHost.HttpControllerRouteHandler} System.Web.Routing.IRouteHandler {System.Web.Http.WebHost.HttpControllerRouteHandler}
- Values {System.Web.Routing.RouteValueDictionary} System.Web.Routing.RouteValueDictionary
Count 2 int
- Keys Count = 2 System.Collections.Generic.Dictionary<string, object>.KeyCollection
[0] "controller" string
[1] "id" string
- Values Count = 2 System.Collections.Generic.Dictionary<string, object>.ValueCollection
[0] "Relationships" object {string}
[1] "PostRelationship" object {string}
这是整个控制器:
[RoutePrefix("api")]
public class RelationshipsController : ApiController
{
private CMDBContext db = new CMDBContext();
[Route("Relationships")]
public IQueryable<Relationship> GetRelationships()
{
return db.Relationships;
}
[Route("Relationships/{id:int}")]
private async Task<Relationship> GetRelationship(int id)
{
Relationship relationship = await db.Relationships.FindAsync(id);
if (relationship == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return relationship;
}
[HttpPost]
[Route("Relationships/PostRelationship")]
private async Task<IHttpActionResult> PostRelationship([FromBody]Relationship relationship)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Relationships.Add(relationship);
await db.SaveChangesAsync();
return CreatedAtRoute("DefaultApi", new { id = relationship.Id }, relationship);
}
[HttpGet]
[Route("Relationships/RelTypes")]
public Dictionary<string, string> RelTypes() // returns a list of available Relationship types
{
var RelTypesDict = new Dictionary<string, string>();
foreach (var type in Relationship.RelTypes)
{
RelTypesDict.Add(type, Regex.Replace(type, @"(\B[A-Z]+?(?=[A-Z][^A-Z])|\B[A-Z]+?(?=[^A-Z]))", " $1")); // expands camel case with spaces for display
}
return RelTypesDict;
}
private bool RelationshipExists(int id)
{
return db.Relationships.Count(e => e.Id == id) > 0;
}
}
和WebApiConfig:
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
和我用来调用它的AJAX:
async function postEdge() { // persists a new edge to data store from form
var ItemLeftId = $('#ItemLeftId').val();
var ItemRightId = $('#ItemRightId').val();
var RelType = $('#ddlRelType').val();
var Description = $('#Description').val();
$.ajax({
method: "POST",
contentType: "application/json; charset=utf-8",
url: '/api/Relationships',
data: {
Id: 0, // TESTING
ItemLeftId: ItemLeftId,
ItemRightId: ItemRightId,
RelType: RelType,
Description: Description,
},
答案 0 :(得分:0)
我发现了-如果您在上方查看,GetRelationship和PostRelationship方法都设置为Private。这是我从另一个基类继承Relationship并使用其他公共方法进行区分时剩下的。愚蠢的错误,但是如果症状不是那么奇怪/无关的话,就会更容易发现。