WebApi icon indicating copy to clipboard operation
WebApi copied to clipboard

FromODataUri attribute, When the type of key is string, and it has leading digits, the key get wrong value

Open kerenkeren opened this issue 6 years ago • 9 comments

When a key of type string get From the url by FromODataUri attribute digits, The key get the first number value and lost Everything Else.

Assemblies affected

FromODataUriAttribute Assembly Microsoft.AspNetCore.OData, Version=7.1.0.21120,

Reproduce steps

The model:

public class Project
  {
        [Key]
       public string Id { get; set; }
     ... 
    }

The Action:

        [EnableQuery]
        public async Task<ActionResult<TDto>> Get([FromODataUri]string keyId)
        {
            ...
        }

The url : http://localhost:5000/project(id='000001')

Expected result

keyId = “000001”

Actual result

keyId = “1”

Additional detail

The problem appears in the ExpressionLexer https://github.com/OData/odata.net/blob/master/src/Microsoft.OData.Core/UriParser/ExpressionLexer.cs The first problem: The input is identified as a number when the first char is a digit https://github.com/OData/odata.net/blob/9ae49e6bf544c580595de5ad0477e999fe745824/src/Microsoft.OData.Core/UriParser/ExpressionLexer.cs#L699 and then get the substring only of the first number value https://github.com/OData/odata.net/blob/9ae49e6bf544c580595de5ad0477e999fe745824/src/Microsoft.OData.Core/UriParser/ExpressionLexer.cs#L930 https://github.com/OData/odata.net/blob/9ae49e6bf544c580595de5ad0477e999fe745824/src/Microsoft.OData.Core/UriParser/ExpressionLexer.cs#L1023 The second: After getting the string that contain only the digit it try to guess the type https://github.com/OData/odata.net/blob/9ae49e6bf544c580595de5ad0477e999fe745824/src/Microsoft.OData.Core/UriParser/ExpressionLexer.cs#L1024 by try parsing to integer, https://github.com/OData/odata.net/blob/9ae49e6bf544c580595de5ad0477e999fe745824/src/Microsoft.OData.Core/UriParser/ExpressionLexer.cs#L1166 in my case it is true so the guess is integer and it is wrong!

kerenkeren avatar Feb 18 '19 16:02 kerenkeren

@kerenkeren Not able to reproduce this at my end. Can you share a simple project where you can reproduce this? Or at the least, can you please share the your metadata or startup.cs.

KanishManuja-MS avatar Feb 20 '19 20:02 KanishManuja-MS

I am getting the same issue. it occurred when using multi-segment keys. you can see reproduce example in: https://github.com/Nomi90/RepreduceWrongODataBindingOnMultiSegmentsKeys/blob/master/IncorrectStringKey/Controllers/ItemsController.cs

Nomi90 avatar Feb 24 '19 10:02 Nomi90

The problem occurs when the key consist 2 segments, like the project linked in the previous comment

kerenkeren avatar Feb 26 '19 09:02 kerenkeren

@KanishManuja-MS We are also facing the same issue. It happens when we are using multi-segment keys.

Is there any update on this? Thanks.

billnguyense avatar Sep 10 '19 10:09 billnguyense

@billnguyense This got missed in the last release. I will tag this appropriately so that we fix this in the next release. If you have investigated this and know a fix for it, we would be happy to review the PR as well.

KanishManuja-MS avatar Sep 10 '19 16:09 KanishManuja-MS

I have the same issue when using Microsoft.AspNetCore.OData version 7.4.1 When do you expect this to be fixed?

BTW: I do notice that this item is tagged with milestone 7.2 and 7.3 (but did not get fixed in any of those). It is not tagged with 7.4, and did not get fixed there either. According to https://github.com/OData/WebApi/milestone/32, 7.5 is expected to be completed this month, but what is the chance of this getting completed in 7.5?

sherland avatar Aug 17 '20 08:08 sherland

same problem 7.5,but Request.RouteValues["para name"] is right I must restore value from there.

kgamecarter avatar Oct 07 '20 09:10 kgamecarter

I wrote a ActionFilter to temporarily fix

public class ODataFixActionFilter : Attribute, IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    { }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        var fixList = context.ActionArguments
            .Where(arg => arg.Value is string)
            .Select(arg => arg.Key)
            .ToList();
        foreach (var key in fixList)
            context.ActionArguments[key] = context.RouteData.Values[key];
    }
}

kgamecarter avatar Oct 07 '20 11:10 kgamecarter

Still same problem. FromQuery works fine, but FromODataUri tries to convert to number first. ...?appId=105E84FF1024

public get([FromODataUri] string appId) => appId = "infinity" public get([FromQuery] string appId) => appId = "105E84FF1024"

SymbioticKilla avatar Aug 19 '24 10:08 SymbioticKilla