Skip to main content
Dynamics 365 Community / Forums / Finance forum / Not able to pass speci...
Finance forum
Suggested answer

Not able to pass special characters (apostrophe character) in the oData URL

editSubscribe (0) ShareShare
ReportReport
Posted on by 85

Hi,

I am trying to integrate Dynamics365 FO using oData rest endpoints in Java. I am not using any oData specific libraries and using simple HTTP client. For testing purposes, I am using Postman to fire the queries and get the response. My observation is that, I am not able to pass the apostrophe(') character in the oData query.

For example, I have a SecurityRole with SecurityRoleIdentifier as :  ,:;\" ' ? | = + . ;; ??? $$ %% ^ &

I encode the above identifier using java.net.URLEncoder and I get the following output: %2C%3A%3B%5C%22+%27+%3F+%7C+%3D+%2B+.+%3B%3B+%3F%3F%3F+%24%24+%25%25+%5E+%26

When I execute: https://<BASE-URL>/data/SecurityRoles?$filter=SecurityRoleIdentifier eq '%2C%3A%3B%5C%22+%27+%3F+%7C+%3D+%2B+.+%3B%3B+%3F%3F%3F+%24%24+%25%25+%5E+%26' I am getting the following error: Syntax error at position 36 in 'SecurityRoleIdentifier eq ',:;\" ' ? | = + . ;; ??? $$ %% ^ &''.

I can see that the filter was correctly formed as expected. On the contrary, the following securityIdentifier GET was successful: !@#$%^&*()SPROLE-2 With SP Chars \\\\ \\\" ,/? <> {}

This identifier is only missing apostrophe and is successful What is the problem with the apostrophe? How it needs to be handled?

Also in this case:

,:;\" ? | = + . ;; ??? $$ %% ^ &

encoded to  -- %2C%3A%3B%5C%22+%3F+%7C+%3D+%2B+.+%3B%3B+%3F%3F%3F+%24%24+%25%25+%5E+%26

I am getting empty result. What is the valid way to encode the values in filter string. I have taken the securityrole as an example but I am sure I will get same behavior for rest of dataentites. Please help!

  • ToddB Profile Picture
    ToddB on at
    RE: Not able to pass special characters (apostrophe character) in the oData URL

    Hi Neeraj,

    I am not sure if this is a product defect or by design; but if you haven't already, you could open a support incident with Microsoft as I have seen other issues reported around "special characters"?

  • Neeraj D Profile Picture
    Neeraj D 85 on at
    RE: Not able to pass special characters (apostrophe character) in the oData URL

    An update on special characters that are not working during the DELETE operation that are directly passed in URL even after URL encoding: +,/,\,?,&,#

  • Neeraj D Profile Picture
    Neeraj D 85 on at
    RE: Not able to pass special characters (apostrophe character) in the oData URL

    Yes Andre, you are absolutely right, having special characters in unique identifiers doesn't make sense. In that, Neeraj's Role was just an example. It can be any random special character. But, as the Dynamics FO is allowing to created SecurityRoleIdentifiers with special characters, I am just wondering how to support them through oData queries. Also, I am not sure and guarantee about the data at the customers' end and neither I can ask them to have these identifiers without sp. characters.

    For GET, my problem is solved by using the $filter query param and encoding the parameters.

    Only problem remains with the DELETE operations where I still see that /data/SecurityRoles('<identifier>') doesn't support certain character even with URL encoding: +,=,/,\ (I guess the parser is failing to understand these encoded characters, for ex if there is '+' in the URL it is still treating it as a space even though encoded to %2B, as + is used for indicating the space)

    For reference, I have opened another question - community.dynamics.com/.../how-to-delete-a-dataentity-entry-in-dynamics-365-finance-and-operations-having-special-characters

    Also, the SystemUsers don't support any special characters in UserId, which I think is a better way of adding the constraint instead of partially failing the operations.

    Would like to hear your thoughts on this and also like to understand if any workaround is possible for All the special characters

  • Suggested answer
    Andre Arnaud de Calavon Profile Picture
    Andre Arnaud de Cal... 283,244 Super User on at
    RE: Not able to pass special characters (apostrophe character) in the oData URL

    Hi Neeraj,

    Wouldn't it be easier to avoid using special characters in security role names? "Neeraj's Role" isn't a commonly used pattern for defining security role's. Usually, I suggest to avoid creating roles specific for users. What is the exact role about? If Neeraj is e.g. performing sales operations, a role named "Sales clerk" is more suitable. If there is a person name in the role, what are the actions when that person is leaving the company and will be replaced with a person with another name? Eventually, if you need it in your way, you can consider using "Neeraj Role" without any special characters.

  • Neeraj D Profile Picture
    Neeraj D 85 on at
    RE: Not able to pass special characters (apostrophe character) in the oData URL

    My requests are successful after modifying the GET URL in the following format:

    data/SecurityRoles?$filter=SecurityRoleIdentifier eq '<UTF-8-ENCODED-IDENTIFIER>'

    All the characters are supported.

    Also note, the quote(') character needs to be appended with an extra quote in the URL. So, for example, if the security role identifier is: Manager's Role, then the URL will be:

    data/SecurityRoles?$filter=SecurityRoleIdentifier eq 'Manager''s Role'

  • Neeraj D Profile Picture
    Neeraj D 85 on at
    RE: Not able to pass special characters (apostrophe character) in the oData URL

    There seems to be a bug on the FO services: I have a following role with SecurityIdentifier as:

    "SecurityRoleIdentifier": "Neeraj's Role"

    The URL that I am triggering is: https://<BASE-FO_URL>/data/SecurityRoles?$filter=SecurityRoleIdentifier eq 'Neeraj%27s+Role'

    I am getting following error with stacktrace:

    "message": "Syntax error at position 35 in 'SecurityRoleIdentifier eq 'Neeraj's Role''.",

               "type": "Microsoft.OData.Core.ODataException",

               "stacktrace": "   at Microsoft.OData.Core.UriParser.ExpressionLexer.ValidateToken(ExpressionTokenKind t)\r\n   at Microsoft.OData.Core.UriParser.Parsers.UriQueryExpressionParser.ParseExpressionText(String expressionText)\r\n   at Microsoft.OData.Core.UriParser.ODataQueryOptionParser.ParseFilterImplementation(String filter, ODataUriParserConfiguration configuration, IEdmType elementType, IEdmNavigationSource navigationSource)\r\n   at Microsoft.OData.Core.UriParser.ODataQueryOptionParser.ParseFilter()\r\n   at System.Web.OData.Query.FilterQueryOption.get_FilterClause()\r\n   at System.Web.OData.Query.FilterQueryOption.ApplyTo(IQueryable query, ODataQuerySettings querySettings, IAssembliesResolver assembliesResolver)\r\n   at Microsoft.Dynamics.Platform.Integration.Services.OData.Query.QueryableExtensions.ApplyQueryOptions(IQueryable queryable, HttpRequestMessage request, ODataQueryOptions queryOptions, Boolean isCollection)\r\n   at Microsoft.Dynamics.Platform.Integration.Services.OData.AxODataController.Get()\r\n   at lambda_method(Closure , Object , Object[] )\r\n   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)\r\n   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Tracing.Tracers.HttpControllerTracer.<ExecuteAsyncCore>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"

  • Neeraj D Profile Picture
    Neeraj D 85 on at
    RE: Not able to pass special characters (apostrophe character) in the oData URL

    I have tried all the other special characters, UTF characters etc. I am only facing issue in quotes and apostrophe.

Helpful resources

Quick Links

New Blog Features Released!

Check out the new community blog features for viewers and authors…

Demystifying Copilot with Sundar Raghavan

Sundar explains how Copilot for Service is meant to function separately...

Business Process Guidance Badges and New…

The Microsoft Success by Design is the framework for implementing Dynamics 365…

Leaderboard

#1
Andre Arnaud de Calavon Profile Picture

Andre Arnaud de Cal... 283,244 Super User

#2
Martin Dráb Profile Picture

Martin Dráb 222,939 Super User

#3
nmaenpaa Profile Picture

nmaenpaa 101,140

Featured topics

Product updates

Dynamics 365 release plans