【问题标题】:Url.Link throws Not Implemented exception in Web Api 2Url.Link 在 Web Api 2 中引发未实现的异常
【发布时间】:2014-11-16 17:27:48
【问题描述】:

我有以下控制器方法:

 [Authorize]
    public IHttpActionResult Post(AlertDataModel model)
    {
        var userID = this.User.Identity.GetUserId();
        var alert = new Alert
        {
            Content = model.Content,
            ExpirationDate = DateTime.Now.AddDays(5),
            UserId = userID
        };

        this.Data.Alerts.Add(alert);
        this.Data.SaveChanges();

        var returnedAlert = new AlertDataModel
        {
            ID = alert.ID,
            Content = alert.Content
        };
        var link = Url.Link(routeName: "DefaultApi", routeValues: new { id = alert.ID });
        var uri = new Uri(link);
        return Created(uri, returnedAlert);
    }

但是我在这一行得到了 NotImplementedException :

var link = Url.Link(routeName: "DefaultApi", routeValues: new { id = alert.ID });

这是完整的错误:

Message: "An error has occurred."
ExceptionMessage: "The method or operation is not implemented."
ExceptionType: "System.NotImplementedException"
StackTrace: " at System.Web.HttpContextBase.get_Response()\ \ at System.Web.UI.Util.GetUrlWithApplicationPath(HttpContextBase context, String url)\ \ at System.Web.Routing.RouteCollection.NormalizeVirtualPath(RequestContext requestContext, String virtualPath)\ \ at System.Web.Routing.RouteCollection.GetVirtualPath(RequestContext requestContext, String name, RouteValueDictionary values)\ \ at System.Web.Http.WebHost.Routing.HostedHttpRouteCollection.GetVirtualPath(HttpRequestMessage request, String name, IDictionary`2 values)\ \ at System.Web.Http.Routing.UrlHelper.GetVirtualPath(HttpRequestMessage request, String routeName, IDictionary`2 routeValues)\ \ at System.Web.Http.Routing.UrlHelper.Route(String routeName, IDictionary`2 routeValues)\ \ at System.Web.Http.Routing.UrlHelper.Link(String routeName, IDictionary`2 routeValues)\ \ at System.Web.Http.Routing.UrlHelper.Link(String routeName, Object routeValues)\ \ at Exam.WebAPI.Controllers.AlertsController.Post(AlertDataModel model) in c:\\Users\\Kiril\\Desktop\\New folder\\Exam.WebAPI\\Controllers\\AlertsController.cs:line 63\ \ at lambda_method(Closure , Object , Object[] )\ \ at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)\ \ at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)\ \ at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)\ \ --- 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.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>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.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.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>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.Web.Http.Controllers.AuthenticationFilterResult.<ExecuteAsync>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.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"

我有以下路由:

config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

我尝试反编译代码,在 ReflectedHttpActionDescriptor.ExecuteAsync 方法中抛出了错误。

有什么想法吗?

【问题讨论】:

  • 也许这个问题将有助于找到解决方案:stackoverflow.com/questions/15022627/…
  • 我看到了,但不幸的是它对我的情况没有太大帮助。
  • 我现在遇到了这个错误,并花了几个小时试图解决它。你找到解决办法了吗?
  • @Elinos 你在使用 OWIN 吗?
  • @Elinos 我使用 OWIN 得到了完全相同的行为。应用程序.UseWebApi()。在我删除 app.UseWebApi() Url.Link 后运行良好。

标签: c# asp.net-web-api asp.net-web-api2


【解决方案1】:

路线名称不正确。您需要使用特定名称装饰 api 方法上的路由属性,然后引用该名称。示例:

[Route(Template = "{id}", Name = "GetThingById")]
public IHttpActionResult Get(int id) {
     return Ok();
}

public IHttpActionResult DoStuff() {
    return Ok(Url.Link("GetThingById", new { id = 5 });
}

【讨论】:

    【解决方案2】:

    如果您使用的是 OWIN,请确保您在启动配置方法中使用了新的 HttpConfiguration 对象:

    public class Startup
    {
        public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
        public static string PublicClientId { get; private set; }
    
        public void Configuration(IAppBuilder app)
        {
            var config = new HttpConfiguration();
    
            ConfigureWebApi(config);
    
            ConfigureAuth(app);
    
            app.UseWebApi(config);
        }
    
        ...
    
    }
    

    我花了几个小时才弄清楚在使用 OWIN 时不应该使用对 GlobalConfiguration 的引用:

    GlobalConfiguration.Configure(WebApiConfig.Register);
    

    【讨论】:

    • 多么好的答案!我正要发疯然后看到这个:)
    • 为什么? OWIN一直很痛苦。一件奇怪的事接二连三。
    • @david 你太棒了!
    【解决方案3】:

    我在我的 api 中使用 OWIN2 进行身份验证。 在 POST 操作中,我将 Location 添加到答案的标题中。 在生成要添加到标头的 URI 的行上引发错误。

        string uri = Url.Link("GetUserById.v2.0", new { id = newUser.Id });
    

    即使我的 Get 用

    装饰,也找不到我的路由名称“GetUserById.v2.0”
        [Route("{id:int}", Name = "GetUserById.v2.0")]
    

    在我使用的 Startup.cs 中

        var config = GlobalConfiguration.Configuration;
    

    配置我的 API。将此行更改为

        var config = new HttpConfiguration();
    

    路线找到了,一切正常:-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-23
      • 2014-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-16
      • 1970-01-01
      • 2014-06-12
      相关资源
      最近更新 更多