none
Altering types returned by class RRS feed

  • Question

  • Ok, the subject is quite broad. I'll explain. I have a class here:

    namespace ACLWebApi.CustomClasses.CustomersBalances
    {
        using System.Xml.Serialization;
    
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
        public class CustomersBalances
        {
            public string Odatacontext { get; set; }
            public CustomerBalances[] Value { get; set; }
        }
    
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        public class CustomerBalances
        {
            public string CustomerNumber { get; set; }
            public string Terms { get; set; }
            public long CreditLimitCustomerCurrency { get; set; }
            public float BalanceDueInCustomerCurrency { get; set; }
            public float BalanceDueInFunctionalCurrency { get; set; }
        }
    }

    It was created from an XSD. You can see the two float values and the long values. When I make a call into my Sage application, I query an API that returns me an array of customers that deserialise straight into an object of type customerBalances. The data types are fixed by Sage.

    Potentially, there could be many thousands of customer records. I need to return the values for the credit limit, and customer balances so that they are all multiplied up by 100 and then returned as integer values. This is because the client that calls my function has implied decimal places, so, for example if the credit limit is 100,000, they store the value in their system as 10000000 which equates to 100,000.00. Same for the balances. They currently come as floats but I need to mutlply up by 100 and convert to integers.

    I could quite easily take the customerBalances array and loop through it each time and make the change to the values as I return an XML doc. An example of one customer is here:

    <CustomersBalances>
        <CustomerBalances>
          <CustomerNumber>CustomerA</CustomerNumber>
          <Terms>0</Terms>
          <CreditLimitCustomerCurrency>100000</CreditLimitCustomerCurrency>
          <BalanceDueInCustomerCurrency>2500.89</BalanceDueInCustomerCurrency>
          <BalanceDueInFunctionalCurrency>2500.89</BalanceDueInFunctionalCurrency>
        </CustomerBalances>
    </CustomersBalances>

    If there were many thousands of customers I don't want to loop through to alter them if I can help it. I'm wondering if there is a way to alter the class to return them in the right format. So setting the values is normal, but when a get occurs they come out with the corrected values. So my example above would be:

    <CustomersBalances>
        <CustomerBalances>
          <CustomerNumber>CustomerA</CustomerNumber>
          <Terms>0</Terms>
          <CreditLimitCustomerCurrency>10000000</CreditLimitCustomerCurrency>
          <BalanceDueInCustomerCurrency>250089</BalanceDueInCustomerCurrency>
          <BalanceDueInFunctionalCurrency>250089</BalanceDueInFunctionalCurrency>
        </CustomerBalances>
    </CustomersBalances>

    Is there a way to avoid having a function to loop through the customerBalances array?

    The code that deserialises the data is:

    CustomerBalances[] customerBalances = new CustomerBalances[] { JsonConvert.DeserializeObject<CustomerBalances>(ResponsePayload) };

    • Edited by MrSnert Thursday, March 14, 2019 12:29 PM Forgot to add code
    Thursday, March 14, 2019 12:26 PM

Answers

  • That's the kind of things I was hoping for. But I need it returned with a different type. So returning it as an integer type. That could work. If I did that for all the 3 values, then my resulting XML would contain 6 fields for the monetary values rather than 3 which, when I serialise the response to XML, would return more information that the client would expect.
    The read only properties are not included when writing out to your file. Of course you would need to try it to know :-)

    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    • Marked as answer by MrSnert Thursday, March 14, 2019 8:41 PM
    Thursday, March 14, 2019 3:02 PM
    Moderator
  • Changing the class structure to this seems to work:

        public class CustomerBalances
        {
            private long _CreditLimitCustomerCurrency;
            private long _BalanceDueInCustomerCurrency;
            private long _BalanceDueInFunctionalCurrency;
    
            public string CustomerNumber { get; set; }
            public string Terms { get; set; }
    
            public long CreditLimitCustomerCurrency
            {
                get { return _CreditLimitCustomerCurrency; }
                set
                {
                    _CreditLimitCustomerCurrency = System.Convert.ToInt64(value) * 100;
                }
            }
    
            public float BalanceDueInCustomerCurrency
            {
                get { return _BalanceDueInCustomerCurrency; }
                set
                {
                    _BalanceDueInCustomerCurrency = System.Convert.ToInt64(value) * 100;
                }
            }
    
            public float BalanceDueInFunctionalCurrency
            {
                get { return _BalanceDueInFunctionalCurrency; }
                set
                {
                    _BalanceDueInFunctionalCurrency = System.Convert.ToInt64(value) * 100;
                }
            }

    • Marked as answer by MrSnert Thursday, March 14, 2019 8:41 PM
    Thursday, March 14, 2019 5:02 PM

All replies

  • Not sure if this will work for you, perhaps a read-only property to do the math and present as int.

    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
    [SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    public class CustomerBalances
    {
        public string CustomerNumber { get; set; }
        public string Terms { get; set; }
        public long CreditLimitCustomerCurrency { get; set; }
        public float BalanceDueInCustomerCurrency { get; set; }
        public float BalanceDueInFunctionalCurrency { get; set; }
        public float BalanceDueInFunctionalCurrencyCalc => 
            (int)BalanceDueInCustomerCurrency * 100;
    }


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Thursday, March 14, 2019 1:23 PM
    Moderator
  • That's the kind of things I was hoping for. But I need it returned with a different type. So returning it as an integer type. That could work. If I did that for all the 3 values, then my resulting XML would contain 6 fields for the monetary values rather than 3 which, when I serialise the response to XML, would return more information that the client would expect.
    Thursday, March 14, 2019 2:38 PM
  • That's the kind of things I was hoping for. But I need it returned with a different type. So returning it as an integer type. That could work. If I did that for all the 3 values, then my resulting XML would contain 6 fields for the monetary values rather than 3 which, when I serialise the response to XML, would return more information that the client would expect.
    The read only properties are not included when writing out to your file. Of course you would need to try it to know :-)

    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    • Marked as answer by MrSnert Thursday, March 14, 2019 8:41 PM
    Thursday, March 14, 2019 3:02 PM
    Moderator
  • Ahh, I shall give it  a whirl once our tech support people sort out my dev server which just ran out of space on the primary drive!
    Thursday, March 14, 2019 3:50 PM
  • Changing the class structure to this seems to work:

        public class CustomerBalances
        {
            private long _CreditLimitCustomerCurrency;
            private long _BalanceDueInCustomerCurrency;
            private long _BalanceDueInFunctionalCurrency;
    
            public string CustomerNumber { get; set; }
            public string Terms { get; set; }
    
            public long CreditLimitCustomerCurrency
            {
                get { return _CreditLimitCustomerCurrency; }
                set
                {
                    _CreditLimitCustomerCurrency = System.Convert.ToInt64(value) * 100;
                }
            }
    
            public float BalanceDueInCustomerCurrency
            {
                get { return _BalanceDueInCustomerCurrency; }
                set
                {
                    _BalanceDueInCustomerCurrency = System.Convert.ToInt64(value) * 100;
                }
            }
    
            public float BalanceDueInFunctionalCurrency
            {
                get { return _BalanceDueInFunctionalCurrency; }
                set
                {
                    _BalanceDueInFunctionalCurrency = System.Convert.ToInt64(value) * 100;
                }
            }

    • Marked as answer by MrSnert Thursday, March 14, 2019 8:41 PM
    Thursday, March 14, 2019 5:02 PM