9

I have the following controller method :

 [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);
    }

But i got NotImplementedException on this row :

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

Here is the full error:

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()"

I have the following routing:

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

I tried to decompile the code and the error was thrown in ReflectedHttpActionDescriptor.ExecuteAsync Method.

Any ideas?

Elinos
  • 121
  • 1
  • 9

3 Answers3

10

If you're using OWIN, ensure that you're using a new HttpConfiguration object in the Startup Configuration method:

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);
    }

    ...

}

It took me several hours to figure out that you shouldn't use a reference to GlobalConfiguration when using OWIN:

GlobalConfiguration.Configure(WebApiConfig.Register);
David
  • 101
  • 1
  • 4
0

The route name is incorrect. You need to decorate the route attribute on the api method with a specific name and then reference that name. Example:

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

public IHttpActionResult DoStuff() {
    return Ok(Url.Link("GetThingById", new { id = 5 });
}
grimurd
  • 2,750
  • 1
  • 24
  • 39
0

I'm using OWIN2 for the authentication in my api. On POST action I'm adding the Location in the header of my answer. An error is thrown on the line that generate the URI to add to the header.

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

My route name "GetUserById.v2.0" was not found even if my Get was decorated with

    [Route("{id:int}", Name = "GetUserById.v2.0")]

In my Startup.cs I was using

    var config = GlobalConfiguration.Configuration;

to configure my API. After changing this line to

    var config = new HttpConfiguration();

the route is found, everything works perfect :-)

Florian SANTI
  • 531
  • 1
  • 5
  • 13