C# OData GetKeyFromUri - Resource not found for the segment 'odata'









up vote
0
down vote

favorite












I've updated from Microsoft.AspNet.OData version 6.0.0 to OData version 7.0.1. The upgrade has broken my ability to get the Id from a path when linking one object to another. Here is my Web API call to add a role to a specific user using the OData standard:



POST: http://localhost:61506/odata/users('bob')/roles/$ref
Request body: "@odata.id":"http://localhost:61506/odata/roles(1)"


The Web API method verifies the user and then makes a call to Helpers.GetKeyFromUri to get the role Id value from the request body.



[HttpPost, HttpPut]
public IHttpActionResult CreateRef([FromODataUri] string key, string navigationProperty, [FromBody] Uri link)

// Ensure the User exists
User user = new User().GetById(key);
if (user == null)

return NotFound();


// Determine which navigation property to use
switch (navigationProperty)

case "roles":
// Get the Role id
int roleId;
try

roleId = Helpers.GetKeyFromUri<int>(Request, link);

catch (Exception ex)

return BadRequest();


// Ensure the Role exists
Role role = new Role().GetById(roleId);
if (role == null)

return NotFound();


// Add the User/Role relationship
user.Roles.Add(role);
user.Update();

break;

default:
return StatusCode(HttpStatusCode.NotImplemented);


return StatusCode(HttpStatusCode.NoContent);



That function looks like this (Originally from here but with updated references: https://github.com/OData/ODataSamples/blob/master/RESTier/Trippin/Trippin/Helpers.cs)



using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http.Routing;
using Microsoft.AspNet.OData.Extensions;
using Microsoft.AspNet.OData.Routing;
using Microsoft.OData.UriParser;

namespace Project1.Extensions

public class Helpers

public static TKey GetKeyFromUri<TKey>(HttpRequestMessage request, Uri uri)

if (uri == null)

throw new ArgumentNullException("uri");


var urlHelper = request.GetUrlHelper() ?? new UrlHelper(request);

var pathHandler = (IODataPathHandler)request.GetRequestContainer().GetService(typeof(IODataPathHandler));

string serviceRoot = urlHelper.CreateODataLink(
request.ODataProperties().RouteName,
pathHandler, new List<ODataPathSegment>());
var odataPath = pathHandler.Parse(serviceRoot, uri.LocalPath, request.GetRequestContainer());

var keySegment = odataPath.Segments.OfType<KeySegment>().FirstOrDefault();
if (keySegment == null)

throw new InvalidOperationException("The link does not contain a key.");


var value = keySegment.Keys.FirstOrDefault().Value;
return (TKey)value;





This line of code is now throwing the following error: Resource not found for the segment 'odata'



var odataPath = pathHandler.Parse(serviceRoot, uri.LocalPath, request.GetRequestContainer());


This worked fine when using OData 6.0.0 but fails in 7.0.1. It seems to have some sort of issue parsing my odata segment or not being able to find it at all. Here is my routing setup if it helps:



public static void Register(HttpConfiguration config)

// Setup the OData routes and endpoints
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "odata",
model: GetEdmModel());

// Enable OData URL querying globally
config.Count().Filter().Select().OrderBy().Expand().MaxTop(null);










share|improve this question

























    up vote
    0
    down vote

    favorite












    I've updated from Microsoft.AspNet.OData version 6.0.0 to OData version 7.0.1. The upgrade has broken my ability to get the Id from a path when linking one object to another. Here is my Web API call to add a role to a specific user using the OData standard:



    POST: http://localhost:61506/odata/users('bob')/roles/$ref
    Request body: "@odata.id":"http://localhost:61506/odata/roles(1)"


    The Web API method verifies the user and then makes a call to Helpers.GetKeyFromUri to get the role Id value from the request body.



    [HttpPost, HttpPut]
    public IHttpActionResult CreateRef([FromODataUri] string key, string navigationProperty, [FromBody] Uri link)

    // Ensure the User exists
    User user = new User().GetById(key);
    if (user == null)

    return NotFound();


    // Determine which navigation property to use
    switch (navigationProperty)

    case "roles":
    // Get the Role id
    int roleId;
    try

    roleId = Helpers.GetKeyFromUri<int>(Request, link);

    catch (Exception ex)

    return BadRequest();


    // Ensure the Role exists
    Role role = new Role().GetById(roleId);
    if (role == null)

    return NotFound();


    // Add the User/Role relationship
    user.Roles.Add(role);
    user.Update();

    break;

    default:
    return StatusCode(HttpStatusCode.NotImplemented);


    return StatusCode(HttpStatusCode.NoContent);



    That function looks like this (Originally from here but with updated references: https://github.com/OData/ODataSamples/blob/master/RESTier/Trippin/Trippin/Helpers.cs)



    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net.Http;
    using System.Web.Http.Routing;
    using Microsoft.AspNet.OData.Extensions;
    using Microsoft.AspNet.OData.Routing;
    using Microsoft.OData.UriParser;

    namespace Project1.Extensions

    public class Helpers

    public static TKey GetKeyFromUri<TKey>(HttpRequestMessage request, Uri uri)

    if (uri == null)

    throw new ArgumentNullException("uri");


    var urlHelper = request.GetUrlHelper() ?? new UrlHelper(request);

    var pathHandler = (IODataPathHandler)request.GetRequestContainer().GetService(typeof(IODataPathHandler));

    string serviceRoot = urlHelper.CreateODataLink(
    request.ODataProperties().RouteName,
    pathHandler, new List<ODataPathSegment>());
    var odataPath = pathHandler.Parse(serviceRoot, uri.LocalPath, request.GetRequestContainer());

    var keySegment = odataPath.Segments.OfType<KeySegment>().FirstOrDefault();
    if (keySegment == null)

    throw new InvalidOperationException("The link does not contain a key.");


    var value = keySegment.Keys.FirstOrDefault().Value;
    return (TKey)value;





    This line of code is now throwing the following error: Resource not found for the segment 'odata'



    var odataPath = pathHandler.Parse(serviceRoot, uri.LocalPath, request.GetRequestContainer());


    This worked fine when using OData 6.0.0 but fails in 7.0.1. It seems to have some sort of issue parsing my odata segment or not being able to find it at all. Here is my routing setup if it helps:



    public static void Register(HttpConfiguration config)

    // Setup the OData routes and endpoints
    config.MapODataServiceRoute(
    routeName: "ODataRoute",
    routePrefix: "odata",
    model: GetEdmModel());

    // Enable OData URL querying globally
    config.Count().Filter().Select().OrderBy().Expand().MaxTop(null);










    share|improve this question























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I've updated from Microsoft.AspNet.OData version 6.0.0 to OData version 7.0.1. The upgrade has broken my ability to get the Id from a path when linking one object to another. Here is my Web API call to add a role to a specific user using the OData standard:



      POST: http://localhost:61506/odata/users('bob')/roles/$ref
      Request body: "@odata.id":"http://localhost:61506/odata/roles(1)"


      The Web API method verifies the user and then makes a call to Helpers.GetKeyFromUri to get the role Id value from the request body.



      [HttpPost, HttpPut]
      public IHttpActionResult CreateRef([FromODataUri] string key, string navigationProperty, [FromBody] Uri link)

      // Ensure the User exists
      User user = new User().GetById(key);
      if (user == null)

      return NotFound();


      // Determine which navigation property to use
      switch (navigationProperty)

      case "roles":
      // Get the Role id
      int roleId;
      try

      roleId = Helpers.GetKeyFromUri<int>(Request, link);

      catch (Exception ex)

      return BadRequest();


      // Ensure the Role exists
      Role role = new Role().GetById(roleId);
      if (role == null)

      return NotFound();


      // Add the User/Role relationship
      user.Roles.Add(role);
      user.Update();

      break;

      default:
      return StatusCode(HttpStatusCode.NotImplemented);


      return StatusCode(HttpStatusCode.NoContent);



      That function looks like this (Originally from here but with updated references: https://github.com/OData/ODataSamples/blob/master/RESTier/Trippin/Trippin/Helpers.cs)



      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Net.Http;
      using System.Web.Http.Routing;
      using Microsoft.AspNet.OData.Extensions;
      using Microsoft.AspNet.OData.Routing;
      using Microsoft.OData.UriParser;

      namespace Project1.Extensions

      public class Helpers

      public static TKey GetKeyFromUri<TKey>(HttpRequestMessage request, Uri uri)

      if (uri == null)

      throw new ArgumentNullException("uri");


      var urlHelper = request.GetUrlHelper() ?? new UrlHelper(request);

      var pathHandler = (IODataPathHandler)request.GetRequestContainer().GetService(typeof(IODataPathHandler));

      string serviceRoot = urlHelper.CreateODataLink(
      request.ODataProperties().RouteName,
      pathHandler, new List<ODataPathSegment>());
      var odataPath = pathHandler.Parse(serviceRoot, uri.LocalPath, request.GetRequestContainer());

      var keySegment = odataPath.Segments.OfType<KeySegment>().FirstOrDefault();
      if (keySegment == null)

      throw new InvalidOperationException("The link does not contain a key.");


      var value = keySegment.Keys.FirstOrDefault().Value;
      return (TKey)value;





      This line of code is now throwing the following error: Resource not found for the segment 'odata'



      var odataPath = pathHandler.Parse(serviceRoot, uri.LocalPath, request.GetRequestContainer());


      This worked fine when using OData 6.0.0 but fails in 7.0.1. It seems to have some sort of issue parsing my odata segment or not being able to find it at all. Here is my routing setup if it helps:



      public static void Register(HttpConfiguration config)

      // Setup the OData routes and endpoints
      config.MapODataServiceRoute(
      routeName: "ODataRoute",
      routePrefix: "odata",
      model: GetEdmModel());

      // Enable OData URL querying globally
      config.Count().Filter().Select().OrderBy().Expand().MaxTop(null);










      share|improve this question













      I've updated from Microsoft.AspNet.OData version 6.0.0 to OData version 7.0.1. The upgrade has broken my ability to get the Id from a path when linking one object to another. Here is my Web API call to add a role to a specific user using the OData standard:



      POST: http://localhost:61506/odata/users('bob')/roles/$ref
      Request body: "@odata.id":"http://localhost:61506/odata/roles(1)"


      The Web API method verifies the user and then makes a call to Helpers.GetKeyFromUri to get the role Id value from the request body.



      [HttpPost, HttpPut]
      public IHttpActionResult CreateRef([FromODataUri] string key, string navigationProperty, [FromBody] Uri link)

      // Ensure the User exists
      User user = new User().GetById(key);
      if (user == null)

      return NotFound();


      // Determine which navigation property to use
      switch (navigationProperty)

      case "roles":
      // Get the Role id
      int roleId;
      try

      roleId = Helpers.GetKeyFromUri<int>(Request, link);

      catch (Exception ex)

      return BadRequest();


      // Ensure the Role exists
      Role role = new Role().GetById(roleId);
      if (role == null)

      return NotFound();


      // Add the User/Role relationship
      user.Roles.Add(role);
      user.Update();

      break;

      default:
      return StatusCode(HttpStatusCode.NotImplemented);


      return StatusCode(HttpStatusCode.NoContent);



      That function looks like this (Originally from here but with updated references: https://github.com/OData/ODataSamples/blob/master/RESTier/Trippin/Trippin/Helpers.cs)



      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Net.Http;
      using System.Web.Http.Routing;
      using Microsoft.AspNet.OData.Extensions;
      using Microsoft.AspNet.OData.Routing;
      using Microsoft.OData.UriParser;

      namespace Project1.Extensions

      public class Helpers

      public static TKey GetKeyFromUri<TKey>(HttpRequestMessage request, Uri uri)

      if (uri == null)

      throw new ArgumentNullException("uri");


      var urlHelper = request.GetUrlHelper() ?? new UrlHelper(request);

      var pathHandler = (IODataPathHandler)request.GetRequestContainer().GetService(typeof(IODataPathHandler));

      string serviceRoot = urlHelper.CreateODataLink(
      request.ODataProperties().RouteName,
      pathHandler, new List<ODataPathSegment>());
      var odataPath = pathHandler.Parse(serviceRoot, uri.LocalPath, request.GetRequestContainer());

      var keySegment = odataPath.Segments.OfType<KeySegment>().FirstOrDefault();
      if (keySegment == null)

      throw new InvalidOperationException("The link does not contain a key.");


      var value = keySegment.Keys.FirstOrDefault().Value;
      return (TKey)value;





      This line of code is now throwing the following error: Resource not found for the segment 'odata'



      var odataPath = pathHandler.Parse(serviceRoot, uri.LocalPath, request.GetRequestContainer());


      This worked fine when using OData 6.0.0 but fails in 7.0.1. It seems to have some sort of issue parsing my odata segment or not being able to find it at all. Here is my routing setup if it helps:



      public static void Register(HttpConfiguration config)

      // Setup the OData routes and endpoints
      config.MapODataServiceRoute(
      routeName: "ODataRoute",
      routePrefix: "odata",
      model: GetEdmModel());

      // Enable OData URL querying globally
      config.Count().Filter().Select().OrderBy().Expand().MaxTop(null);







      odata






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 10 at 18:03









      user1624184

      427




      427



























          active

          oldest

          votes











          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53241904%2fc-sharp-odata-getkeyfromuri-resource-not-found-for-the-segment-odata%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown






























          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53241904%2fc-sharp-odata-getkeyfromuri-resource-not-found-for-the-segment-odata%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          Barbados

          How to read a connectionString WITH PROVIDER in .NET Core?

          Node.js Script on GitHub Pages or Amazon S3