Accessing Query Parameters in Service Functions

Be easy on me I'm new here. :slightly_smiling_face:

How do I access to the query parameters inside Service Functions? With DMVC Framework we would use:

if Context.Request.QueryStringParamExists('class') then
Where.Add(TWhere.Create('and', (Context.Request.QueryStringParam('class'))));

I'm not finding anything in the documentation.

Thank you..

In XData you don't need to do that, because your mapping is supposed to automatically convert the query parameters into the method parameters.

The process is explained in the documentation topic parameter binding and contains examples of query binding like this:

[HttpPost] function Multiply([FromQuery] A: double; [FromQuery] B: double): double;

That maps A and B query parameters automatically like:

POST /tms/xdata/MathService/Multiply?a=5&b=8 HTTP/1.1

Using [FromQuery] makes the parameter required. That is not what we need. They are optional and are not fixed to variables.

We need wildcards as query parameters to be optional and may contain anything.

Example: http://xxx.xxx.xxx.xxx\list?itemclass=stocked&onhand>20&bettyisblue=true

itemclass and onhand do not exist anywhere in the code. We parse the query parameters and use them to build our special sql queries.

Using your format:

[HttpGet, route('list')]
Function GetSimpleList([FromQuery] Filter:String):TObjectlist<TLineItemList>;

Does not work as needed. First, it requires the filter param, and then it creates something like:
http://xxx.xxx.xxx.xxx\list?filter=itemclass%19stocked which is incorrect for our needs. The filter= should not be there. It should be Itemclass=stocked

Maybe I am doing it wrong or there are different options I am not aware of.

Maybe I need to use the System.Net.URLClient unit and parse the URL from TXDataOperationContext.Current.Request.RawUri. This way I have no fixed limitations.

You can check the query parameters this way:

uses Sparkle.Utils;

var Query: TQueryString;
begin
  Query := TQueryString.Create(Context.Request.Uri.Query);
end;

Then you can use the following functions and properties of TQueryString:

    function ParamCount: Integer;
    function GetValue(const Name: string): string;
    property Values[const Name: string]: string read GetValue; default;
    property Params[const Index: Integer]: TNameValuePair read GetParam;

I was just showing you the things that makes XData stand out. But if it doesn't fit your needs, that's fine, you go to a lower level.
This "custom filter" mechanism is even higher level if you mix XData and Aurelius, as explained here: TMS Software | Blog

But as I said, you can go low level if you need to.

And by the way, you can have optional query parameters by using Nullable<T> types, or default parameter values, or you can even use a class DTO as a query parameter so that the mapped fields of such class will be the query parameters.

Thank you Wagner!

You created a great product and provided excellent support. I appreciate your talents and helping me get up and going.

Many thanks again...

1 Like