【发布时间】:2019-11-25 17:04:37
【问题描述】:
我的控制器上的所有操作都有属性路由(尽管定义了默认的常规路由)。我已经(我认为)尝试了是否使用 [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,
},
【问题讨论】:
标签: c# asp.net-mvc-5 asp.net-web-api2 asp.net-web-api-routing