BO4E/meta/Bo4eUri.cs
/// <summary>
///     The query object / dictionary returned by this method allows to search for Business Objects.
///     Basically this method reverses what is done in <see cref="GetUri(BusinessObject, bool)" />.
/// </summary>
/// The path segments of the URI represent components of the (composite) key of the
/// Business Object. All key components, annotated with the
/// <see cref="BoKey" />
/// attribute
/// are obligatory fields, yet not all obligatory fields are key components. Hence it is
/// in general not possible to create a valid Business Object only from its key values.
/// This is why the return type of this method is just a general JObject but not a valid
/// Business Object.
/// <returns>A dictionary with boKey:boKeyValue pairs.</returns>
The query object / dictionary returned by this method allows to search for Business Objects.
Basically this method reverses what is done in
The path segments of the URI represent components of the (composite) key of the
Business Object. All key components, annotated with the
.
The query object / dictionary returned by this method allows to search for Business Objects . Basically this method reverses what is done in The path segments of the URI represent components of the ( composite ) key of the Business Object . All key components annotated with the .
public JObject GetQueryObject(Type boType = null, int i = 0)
        {
            var result = new JObject();
            if (boType == null) 
                boType = GetBoType();
            result.Add("boTyp", boType.Name.ToUpper());
            foreach (var keyProp in GetKeyProperties(boType))
            {
                var keyPropName = keyProp.Name;
                var jpa = keyProp.GetCustomAttribute<JsonPropertyAttribute>();
                if (jpa?.PropertyName != null) keyPropName = jpa.PropertyName;
                string keyValue;
                try
                {
                    keyValue = FullyUnescapeDataString(Segments[++i]);
                }
                catch (IndexOutOfRangeException)
                {
                    break; 
                }
                if (keyValue.EndsWith("/")) keyValue = keyValue.Substring(0, keyValue.Length - 1);
                if (keyProp.PropertyType == typeof(string))
                {
                    result.Add(keyPropName, keyValue == NullKeyPlaceholder ? null : keyValue);
                }
                else if (keyProp.PropertyType == typeof(int))
                {
                    if (int.TryParse(keyValue, out var keyValueInt))
                        result.Add(keyPropName, keyValueInt);
                    else
                        throw new ArgumentException(
                            $"Key segment {keyPropName} could not be parsed as int although an integer type was expected!");
                }
                else if (keyProp.PropertyType.IsSubclassOf(typeof(BusinessObject)))
                {
                    var subresult = GetQueryObject(keyProp.PropertyType, i - 1);
                    result.Add(keyPropName, subresult);
                }
                else
                {
                    throw new NotImplementedException($"Using {keyProp.PropertyType} as [BoKey] is not supported yet.");
                }
            }
            var query = HttpUtility.ParseQueryString(Query);
            var boProps = GetBoType().GetProperties().Select(p => p.Name);
            if (
                query.AllKeys
                    .Contains("filter")) 
            {
                var filter = query.Get("filter");
                foreach (Match match in FilterAndPattern.Matches(filter))
                    if (boProps.Contains(match.Groups["key"].Value, StringComparer.OrdinalIgnoreCase))
                        result[match.Groups["key"].Value] = match.Groups["value"].Value;
            }
            return result;
        }
public JObject GetQueryObject ( Type boType = null , int i = 0 ) { var result = new JObject ( ) ; if ( boType == null ) boType = GetBoType ( ) ; result . Add ( " " , boType . Name . ToUpper ( ) ) ; foreach ( var keyProp in GetKeyProperties ( boType ) ) { var keyPropName = keyProp . Name ; var jpa = keyProp . GetCustomAttribute < JsonPropertyAttribute > ( ) ; if ( jpa ? . PropertyName != null ) keyPropName = jpa . PropertyName ; string keyValue ; try { keyValue = FullyUnescapeDataString ( Segments [ ++ i ] ) ; } catch ( IndexOutOfRangeException ) { break ; } if ( keyValue . EndsWith ( " " ) ) keyValue = keyValue . Substring ( 0 , keyValue . Length - 1 ) ; if ( keyProp . PropertyType == typeof ( string ) ) { result . Add ( keyPropName , keyValue == NullKeyPlaceholder ? null : keyValue ) ; } else if ( keyProp . PropertyType == typeof ( int ) ) { if ( int . TryParse ( keyValue , out var keyValueInt ) ) result . Add ( keyPropName , keyValueInt ) ; else throw new ArgumentException ( $" Key segment  { keyPropName }  could not be parsed as int although an integer type was expected! " ) ; } else if ( keyProp . PropertyType . IsSubclassOf ( typeof ( BusinessObject ) ) ) { var subresult = GetQueryObject ( keyProp . PropertyType , i - 1 ) ; result . Add ( keyPropName , subresult ) ; } else { throw new NotImplementedException ( $" Using  { keyProp . PropertyType }  as [BoKey] is not supported yet. " ) ; } } var query = HttpUtility . ParseQueryString ( Query ) ; var boProps = GetBoType ( ) . GetProperties ( ) . Select ( p => p . Name ) ; if ( query . AllKeys . Contains ( " " ) ) { var filter = query . Get ( " " ) ; foreach ( Match match in FilterAndPattern . Matches ( filter ) ) if ( boProps . Contains ( match . Groups [ " " ] . Value , StringComparer . OrdinalIgnoreCase ) ) result [ match . Groups [ " " ] . Value ] = match . Groups [ " " ] . Value ; } return result ; }
The query object / dictionary returned by this method allows to search for Business Objects.
The query object / dictionary returned by this method allows to search for Business Objects .
// Method is called recursively if sub-BOs are part of the key. To distinguish between // top level and recursive calls, check the value of boType and i. // top level call // The order of the FieldInfos is the same as the JsonProperty.Order attribute of the // business objects is the same as the order of the BO key values encoded in the URI // path segments. // no arguments at all. /*if (keyField.FieldType.IsEnum)
                    {
                        Enum.TryParse<>
                        if( Enum.TryParse(keyValue, out var resultEnum);
                    }
                    else*/ // currently this pattern only supports AND concatenation, not OR. result should contain multiple JObjects
A dictionary with boKey:boKeyValue pairs.
A dictionary with boKey : boKeyValue pairs .
boType
Type
i
int
see
attribute
are obligatory fields, yet not all obligatory fields are key components. Hence it is
in general not possible to create a valid Business Object only from its key values.
This is why the return type of this method is just a general JObject but not a valid
Business Object.
attribute are obligatory fields yet not all obligatory fields are key components . Hence it is in general not possible to create a valid Business Object only from its key values . This is why the return type of this method is just a general JObject but not a valid Business Object .