Is your feature request related to a problem? Please describe.
The CustomSearch parameter on GET /dwapi/ecommerce/orders/search is impossible to use correctly from the Swagger UI, because the documentation for its syntax is destroyed by the doc renderer.
The XML doc on OrderSearchRequest.CustomSearch describes the format using <c> tags around tokens containing angle brackets:
/// Format: <c>fieldname<op>value</c> where op is <c>eq</c>, <c>in</c>, or <c>like</c>.
/// For <c>in</c>, pipe-separate multiple values: <c>fieldname<in>val1|val2</c>.
/// Example: <c>OrderCustomerCountryCode<eq>DK;OrderCurrencyCode<in>DKK|EUR</c>
NSwag strips <c> tags without substituting markdown backticks, so /dwapi/api.json ends up containing the operators as bare angle-bracket tokens:
"name": "CustomSearch",
"in": "query",
"description": "One or more field-specific filters, semicolon-separated.\nFormat: fieldname<op>value where op is eq, in, or like.\nFor in, pipe-separate multiple values: fieldname<in>val1|val2.\nExample: OrderCustomerCountryCode<eq>DK;OrderCurrencyCode<in>DKK|EUR"
Swagger UI renders parameter descriptions as Markdown with raw HTML enabled. <op>, <eq> and <in> are therefore parsed as unknown HTML tags and rendered as nothing. What a consumer actually reads on /dwapi/docs is:
One or more field-specific filters, semicolon-separated.
Format: fieldnamevalue where op is eq, in, or like.
For in, pipe-separate multiple values: fieldnameval1|val2.
Example: OrderCustomerCountryCodeDK;OrderCurrencyCodeDKK|EUR
The only visible separator left is the pipe, so the documented syntax reads as field|value. We lost time building &CustomSearch=OrderType|Units and could not work out why it had no effect.
A second problem makes this much worse: invalid CustomSearch input fails silently. FieldSearch.TryParse returns false when no token contains a recognised operator, and OrdersController.BuildSearchFilter simply does not set filter.FieldSearches in that case. Likewise, OrderRepository.GetFieldSearchFilterClause continues past any field name that is not in its whitelist. Either way the endpoint returns HTTP 200 with the full unfiltered result set and no warning. There is no feedback signal telling the caller their filter was discarded, so a wrong syntax is indistinguishable from a filter that legitimately matches everything.
Describe the solution you'd like
-
Make the syntax survive the renderer. Put literal markdown backticks in the XML doc instead of relying on <c>, so the description in api.json is already markdown-safe and Swagger UI renders the operators inside a code span:
/// Format: `fieldname<op>value` where op is `eq`, `in`, or `like`.
/// For `in`, pipe-separate multiple values: `fieldname<in>val1|val2`.
/// Example: `OrderCustomerCountryCode<eq>DK;OrderCurrencyCode<in>DKK|EUR`
-
Fail loudly on unusable input. Return 400 Bad Request from GET /dwapi/ecommerce/orders/search when CustomSearch is non-empty but yields no usable filter — either because no token parsed, or because every field named is outside the whitelist. The response body should name the offending token. Silently returning an unfiltered 200 is the single biggest reason this took as long as it did to diagnose.
-
Optionally, document which field names are accepted (the GetFieldSearchFilterClause whitelist plus everything from Services.OrderFields.GetOrderFields()), since that is currently only discoverable by reading the source.
Additional context
Files involved:
Dynamicweb.Frontend.Classic.Api.Ecommerce/Controllers/OrderSearchRequest.cs — the XML doc on CustomSearch
Dynamicweb.Frontend.Classic.Api.Ecommerce/Controllers/OrdersController.cs — BuildSearchFilter, where a failed parse is dropped
src/Features/Ecommerce/Dynamicweb.Ecommerce/Orders/FieldSearch.cs — TryParse, same rendering issue in its <remarks>
src/Features/Ecommerce/Dynamicweb.Ecommerce/Orders/OrderRepository.cs — GetFieldSearchFilterClause, where a non-whitelisted field is skipped
Steps to reproduce the documentation defect:
- Open
/dwapi/docs, expand GET /dwapi/ecommerce/orders/search, and read the CustomSearch description — the operators are absent.
- Fetch
/dwapi/api.json and search for "name": "CustomSearch" — the operators are present as bare <op> / <eq> / <in>, confirming the loss happens at render time, not generation time.
Steps to reproduce the silent-failure behaviour, against a solution with a custom order field OrderType:
# discarded filter, returns 200 and every order
curl -H "Authorization: Bearer $TOKEN" \
"https://<host>/dwapi/ecommerce/orders/search?CustomSearch=OrderType|UNIT"
# working filter
curl -H "Authorization: Bearer $TOKEN" \
"https://<host>/dwapi/ecommerce/orders/search?CustomSearch=OrderType%3Ceq%3EUNIT"
Both return 200 OK; only the second one filters.
Scope check: we walked every description in a generated api.json looking for bare HTML-like tokens and found three. The other two — ManufacturerViewModel.logo (<img>) and BomGroupViewModel.noneSelectedText (<option>) — are cosmetic, since the surrounding prose still makes sense without them. CustomSearch is the only one where the lost text is the specification.
Best Regards
Nuno Aguiar
Is your feature request related to a problem? Please describe.
The
CustomSearchparameter onGET /dwapi/ecommerce/orders/searchis impossible to use correctly from the Swagger UI, because the documentation for its syntax is destroyed by the doc renderer.The XML doc on
OrderSearchRequest.CustomSearchdescribes the format using<c>tags around tokens containing angle brackets:NSwag strips
<c>tags without substituting markdown backticks, so/dwapi/api.jsonends up containing the operators as bare angle-bracket tokens:Swagger UI renders parameter descriptions as Markdown with raw HTML enabled.
<op>,<eq>and<in>are therefore parsed as unknown HTML tags and rendered as nothing. What a consumer actually reads on/dwapi/docsis:The only visible separator left is the pipe, so the documented syntax reads as
field|value. We lost time building&CustomSearch=OrderType|Unitsand could not work out why it had no effect.A second problem makes this much worse: invalid
CustomSearchinput fails silently.FieldSearch.TryParsereturnsfalsewhen no token contains a recognised operator, andOrdersController.BuildSearchFiltersimply does not setfilter.FieldSearchesin that case. Likewise,OrderRepository.GetFieldSearchFilterClausecontinues past any field name that is not in its whitelist. Either way the endpoint returns HTTP 200 with the full unfiltered result set and no warning. There is no feedback signal telling the caller their filter was discarded, so a wrong syntax is indistinguishable from a filter that legitimately matches everything.Describe the solution you'd like
Make the syntax survive the renderer. Put literal markdown backticks in the XML doc instead of relying on
<c>, so the description inapi.jsonis already markdown-safe and Swagger UI renders the operators inside a code span:Fail loudly on unusable input. Return
400 Bad RequestfromGET /dwapi/ecommerce/orders/searchwhenCustomSearchis non-empty but yields no usable filter — either because no token parsed, or because every field named is outside the whitelist. The response body should name the offending token. Silently returning an unfiltered 200 is the single biggest reason this took as long as it did to diagnose.Optionally, document which field names are accepted (the
GetFieldSearchFilterClausewhitelist plus everything fromServices.OrderFields.GetOrderFields()), since that is currently only discoverable by reading the source.Additional context
Files involved:
Dynamicweb.Frontend.Classic.Api.Ecommerce/Controllers/OrderSearchRequest.cs— the XML doc onCustomSearchDynamicweb.Frontend.Classic.Api.Ecommerce/Controllers/OrdersController.cs—BuildSearchFilter, where a failed parse is droppedsrc/Features/Ecommerce/Dynamicweb.Ecommerce/Orders/FieldSearch.cs—TryParse, same rendering issue in its<remarks>src/Features/Ecommerce/Dynamicweb.Ecommerce/Orders/OrderRepository.cs—GetFieldSearchFilterClause, where a non-whitelisted field is skippedSteps to reproduce the documentation defect:
/dwapi/docs, expandGET /dwapi/ecommerce/orders/search, and read theCustomSearchdescription — the operators are absent./dwapi/api.jsonand search for"name": "CustomSearch"— the operators are present as bare<op>/<eq>/<in>, confirming the loss happens at render time, not generation time.Steps to reproduce the silent-failure behaviour, against a solution with a custom order field
OrderType:Both return
200 OK; only the second one filters.Scope check: we walked every
descriptionin a generatedapi.jsonlooking for bare HTML-like tokens and found three. The other two —ManufacturerViewModel.logo(<img>) andBomGroupViewModel.noneSelectedText(<option>) — are cosmetic, since the surrounding prose still makes sense without them.CustomSearchis the only one where the lost text is the specification.Best Regards
Nuno Aguiar