WebApi2 CreatedAtRoute路由到不同的控制器

WebApi2 CreatedAtRoute路由到不同的控制器

问题描述:

我使用路由属性创建一个嵌套的路线如此创建一个新的WebAPI:

I'm creating a new webapi using attribute routing to create a nested route as so:

    // PUT: api/Channels/5/Messages
    [ResponseType(typeof(void))]
    [Route("api/channels/{id}/messages")]
    public async Task<IHttpActionResult> PostChannelMessage(int id, Message message)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        if (id != message.ChannelId)
        {
            return BadRequest();
        }

        db.Messages.Add(message);
        await db.SaveChangesAsync();

        return CreatedAtRoute("DefaultApi", new { id = message.Id }, message);
    }

然而,我要回未嵌套即一个路线:

I however want to return a route that isn't nested i.e.:

/api/Messages/{id}

该消息控制器上所定义。然而上述CreatedAtRoute呼叫没有解决这个路线,而不是抛出。难道我做错了什么,或者它不支持路由到不同的API控制器? N.B.我想打的路线不是属性的路线,只是一个默认的。

which is defined on the messages controller. However The CreatedAtRoute call above is not resolving this route and instead throwing. Have I done something wrong, or does it not support routing to different api controller? n.b. the route I am trying to hit is not an attribute route, just a default one.

唯一的例外是:

消息:发生了错误。
  ExceptionMessage:UrlHelper.Link不能返回null。
  ExceptionType:System.InvalidOperationException
  堆栈跟踪:在System.Web.Http.Results.CreatedAtRouteNegotiatedContentResult 1.Execute()在System.Web.Http.Results.CreatedAtRouteNegotiatedContentResult 1.ExecuteAsync(的CancellationToken的CancellationToken)的系统.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext()---从previous位置堆栈跟踪,其中的例外是在系统---扔在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)结束.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification在System.Runtime.CompilerServices.TaskAwaiter 1.GetResult()在System.Web.Http.Controllers.ActionFilterResult&LT(任务任务); ExecuteAsync&GT; d__2.MoveNext( )---从previous位置堆栈跟踪,其中的例外是在抛出---在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)结束System.Runtime.CompilerServices.TaskAwaiter 1.GetResult()在System.Web.Http.Dispatcher.HttpControllerDispatcher.d__0.MoveNext()

Message: "An error has occurred." ExceptionMessage: "UrlHelper.Link must not return null." ExceptionType: "System.InvalidOperationException" StackTrace: " at System.Web.Http.Results.CreatedAtRouteNegotiatedContentResult1.Execute() at System.Web.Http.Results.CreatedAtRouteNegotiatedContentResult1.ExecuteAsync(CancellationToken cancellationToken) at System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.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.TaskAwaiter1.GetResult() at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.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.TaskAwaiter1.GetResult() at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__0.MoveNext()"

如果它不支持这个,什么是返回一个201的正规途径,我能做到这一点的重构安全的方式?

If it doesn't support this, what is the canonical way to return a 201 and can I do it in a refactor safe way?

哦,亲爱的,这可能是回答我的问题的新纪录。

Oh dear, this may be a new record for answering my own question.

return CreatedAtRoute("DefaultApi", new { controller = "messages", id = message.Id }, message);

的伎俩。即,明确指定控制器。我曾这样我们通过观察,这个例外是涉及到UrlHelper和读取其文档...

does the trick. i.e. explicitly specifying the controller. I worked this our by seeing that the exception was related to the UrlHelper and reading its docs...