Solved

C#.NET Inheritance best practice

Posted on 2015-01-24
7
199 Views
Last Modified: 2015-01-26
I have the below abstract class called ProcessorGateway.

using System;
using System.Data;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Text;

namespace Gateways
{
    [Serializable]
	public abstract class ProcessorGateway
    {
        public abstract void AuthorizeTransaction(ProcessorGatewayContext context);

        public abstract ProcessorGatewayContext NewContext();

        private bool _isLive;

        public bool IsLive
        {
            get { return _isLive; }
            set { _isLive = value; }
        }
    }
}

Open in new window


 Is it considered bad practice to add the AuthroizeNet using directive, and the GetTransactionDetailsResponseReason method as below?
 Please note that one of the parameters being passed to GetTransactionDetailsResponseReason is of type AuthorizeNetGatewayResponseInfo.
 In other words if ProcessorGateway is an abstract class of type Animal, I am essentially passing to one of it's methods a type called Dog.
 Is this bad practice? Is the abstract class suppose to be very generic or is it OK to have certain methods apply to only certain types of ProcessorGateway?

using System;
using System.Data;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Text;
using Gateways.AuthorizeNet;

namespace Gateways
{
    [Serializable]
	public abstract class ProcessorGateway
    {
        public abstract void AuthorizeTransaction(ProcessorGatewayContext context);
		
		public abstract string GetTransactionDetailsResponseReason(ProcessorGatewayContext context, string _transID, AuthorizeNetGatewayResponseInfo responseInfo);

        public abstract ProcessorGatewayContext NewContext();

        private bool _isLive;

        public bool IsLive
        {
            get { return _isLive; }
            set { _isLive = value; }
        }
    }
}

Open in new window

0
Comment
Question by:pzozulka
7 Comments
 
LVL 35

Assisted Solution

by:Miguel Oz
Miguel Oz earned 166 total points
ID: 40568650
IF this method (GetTransactionDetailsResponseReason) is only used by some of your derived classes then the answer is NO, because the abstract class represents all the common functionality  required by all your subclasses. You may consider adding an extra subclass if the method is being used by a handful of classes.
In your example, Animal class is the base class then Dog could contain all common functionality for all dogs (e.g. Bark). Then a GermanSheppard class can implement/override Bark if needed.
0
 
LVL 8

Author Comment

by:pzozulka
ID: 40568667
Here's what I'm trying to do. From my main class I need to check if certain variables are true, and if so, I need to set the ProcessorGateway.IsLive property to true. I then need to make a call to the GetTransactionDetailsResponseReason method located inside AuthorizeNetGateway class, and make use of the IsLive property from there.

I though of two ways of doing this.

First Option
As per the original post, create an abstract method inside of ProcessorGateway, and override it in AuthorizeNetGateway. (Again, as per original post, don't know if this is good practice).

From my main class:
ProcessorGateway Gateway = new AuthorizeNetGateway();
if(abc == true)
{
   Gateway.IsLive = true;
}
string reason = Gateway.GetTransactionDetailsResponseReason(context, _transID, responseInfo);

Open in new window

Second Option
Don't set Gateway.IsLive to true, don't override anything in the AuthorizeNetGateway class, don't modify the the ProcessorGateway abstract class, and just pass the IsLive boolean as a parameter like so:
if(abc == true)
{
   bool isLive = true;
}
AuthorizeNetGateway authNetGateway = new AuthorizeNetGateway();
string reason = authNetGateway.GetTransactionDetailsResponseReason(context, _transID, responseInfo, isLive);

Open in new window


Which way is better? Looking at existing code, previous developers used the inheritance way (First Option) a lot. The only reason I'm skeptical of this approach is because of my the concerns in my original post up top.

Just for reference, here is the AuthorizeNetGateway class:

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Net;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.Xml.Linq;
using System.Xml;
using Gateways.AuthorizeNet;

namespace Gateways
{
    [Serializable]
	public class AuthorizeNetGateway : ProcessorGateway
    {
        const string LIVE_URL = "https://secure.authorize.net/gateway/transact.dll";
        const string TEST_URL = "https://test.authorize.net/gateway/transact.dll";

        private const int RESPONSE_TRANSACTIONID = 6;
        private const int RESPONSE_RESPONSECODE = 0;
        private const int RESPONSE_MESSAGE = 3;

        public override ProcessorGatewayContext NewContext()
        {
            return new AuthorizeNetGatewayContext();
        }
		
		 public override string GetTransactionDetailsResponseReason(ProcessorGatewayContext context, string transID, AuthorizeNetGatewayResponseInfo responseInfo)
        {
            const string LIVE_API = "https://api.authorize.net/xml/v1/request.api";
            const string TEST_API = "https://apitest.authorize.net/xml/v1/request.api";
			
			string name = string.Empty; 
            string transactionKey = string.Empty;  
            string transactionID = transID;

            AuthorizeNetGatewayContext Ang = context as AuthorizeNetGatewayContext;

            if (Ang == null) throw new Exception("Improper Gateway context used for AuthorizeNet Processor Gateway");

            try
            {

                if (IsLive)
                {
					// ...
					

Open in new window

0
 
LVL 8

Author Comment

by:pzozulka
ID: 40568681
Miguel: I guess my question is it good practice to have the following method in the Animal base class:

abstract class Animal
{
     makeNoise( Dog animalType )
     {
         animalType.Bark()
     }
}

So although it seems like makeNoise could pertain to any derived classes of type Animal, the param being passed to the makeNoise can only be of type Dog. Furthermore, I would probably need to also make the using directive such as : using Dog;
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 32

Accepted Solution

by:
it_saige earned 167 total points
ID: 40568750
pzozulka, in your Animal example.  That would most certainly not be good practice.  Good practice would be to make the makeNoise method have a parameter that represents the Animal class.  Consider the following:
using System;
using System.Collections.Generic;

namespace EE_Q28603282
{
	class Program
	{
		static void Main(string[] args)
		{
			var animals = new List<Animal>() { new Dog(), new Cat(), new Lion(), new Fish() };
			Console.WriteLine("Making animal noises");
			foreach (var animal in animals)
				Animal.MakeNoise(animal);
			Console.ReadLine();
		}
	}

	abstract class Animal
	{
		public static void MakeNoise(Animal animal)
		{
			animal.MakeNoise();
		}

		internal virtual void MakeNoise()
		{
			Console.WriteLine("A {0} does not make any noise.", this);
		}

		public override string ToString()
		{
			return "Animal";
		}
	}

	class Lion : Animal
	{
		internal override void MakeNoise()
		{
			Console.WriteLine("A {0} ROARS!!!", this);
		}

		public override string ToString()
		{
			return "Lion";
		}
	}

	class Dog : Animal
	{
		internal override void MakeNoise()
		{
			Console.WriteLine("A {0} BARKS!!!", this);
		}

		public override string ToString()
		{
			return "Dog";
		}
	}

	class Cat : Animal
	{
		internal override void MakeNoise()
		{
			Console.WriteLine("A {0} MEOWS!!!", this);
		}

		public override string ToString()
		{
			return "Cat";
		}
	}

	class Fish : Animal
	{
		public override string ToString()
		{
			return "Fish";
		}
	}
}

Open in new window

Produces the following output -Capture.JPG-saige-
0
 
LVL 74

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 167 total points
ID: 40568811
I agree with it_saige that what you have with your Animal class isn't a good approach, but I disagree that you should introduce a new static method just for the sake of calling the method(s) of your Animal class. There's no benefit that I can see to having that method--it's just going to do the same thing that you can do yourself, which is call the abstract method. For example, just by changing the call in the main application:

class Program
{
    static void Main(string[] args)
    {
        var animals = new List<Animal>() { new Dog(), new Cat(), new Lion(), new Fish() };
        Console.WriteLine("Making animal noises");
        foreach (var animal in animals)
            animal.MakeNoise();
        Console.ReadLine();
    }
}

Open in new window


...I still have the same behavior, without the cost of one additional call.

So although it seems like makeNoise could pertain to any derived classes of type Animal, the param being passed to the makeNoise can only be of type Dog.
What would be your purpose for doing this?
0
 
LVL 32

Expert Comment

by:it_saige
ID: 40568820
@kaufmed...  The static method was just to show how it could be done, I guess I should have stipulated that in the example, you could still just call the MakeNoise method for each animal instance without using the static method.  I do agree with you, though, that there is no benefit to making the static call over the abstract method.

-saige-
0
 
LVL 8

Author Comment

by:pzozulka
ID: 40569464
kaufmed:
What would be your purpose for doing this?

The Dog class example I've been using is referring to the AuthorizeNetGatewayResponseInfo class -- implementation below -- which implements over 100 new objects of type ResponseInfo, so as you can see it's expensive.

Going back to our example, the makeNoise(Dog dog) method is called from my main class using a loop hundreds of times. I don't want to instantiate the Dog object each and every time because that would be even more expensive. So what I did, is before the loop began in my main class, I instantiated the Dog class once, and then pass it to the makeNoise class every time. Much less expensive this way I think.

So in other words, I don't have to pass the Dog class to makeNoise, but then I would have to instantiated it each and every time in the derived overriden method each time -- very expensive.

Please see post ID: 40568667 to see what I'm trying to accomplish.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Gateways.AuthorizeNet
{
    public class AuthorizeNetGatewayResponseInfo
    {
        public List<ResponseInfo> ResponseInfoList = null;

        public AuthorizeNetGatewayResponseInfo()
        {
            ResponseInfoList = new List<ResponseInfo>()
            {
                { new ResponseInfo(1, "This transaction has been approved.") },
                { new ResponseInfo(2, "This transaction has been declined.") },
                { new ResponseInfo(3, "This transaction has been declined.") },
                { new ResponseInfo(4, "This transaction has been declined.") },
                { new ResponseInfo(5, "A valid amount is required.") },
                { new ResponseInfo(6, "The credit card number is invalid.") },
                { new ResponseInfo(7, "The credit card expiration date is invalid.") },
                { new ResponseInfo(8, "The credit card has expired.") },
                { new ResponseInfo(9, "The ABA code is invalid.") },
                { new ResponseInfo(10, "The account number is invalid.") },
                { new ResponseInfo(11, "A duplicate transaction has been submitted.") },
                { new ResponseInfo(12, "An authorization code is required but not present.") },
                { new ResponseInfo(13, "The merchant API Login ID is invalid or the account is inactive.") },
                { new ResponseInfo(14, "The Referrer or Relay Response URL is invalid.") },
                { new ResponseInfo(15, "The transaction ID is invalid.") },
                { new ResponseInfo(16, "The transaction was not found.") },
                { new ResponseInfo(17, "The merchant does not accept this type of credit card.") },
                { new ResponseInfo(18, "ACH transactions are not accepted by this merchant.") },
                { new ResponseInfo(19, "An error occurred during processing. Please try again in 5 minutes.") },
                { new ResponseInfo(20, "An error occurred during processing. Please try again in 5 minutes.") },
                { new ResponseInfo(21, "An error occurred during processing. Please try again in 5 minutes.") },
                { new ResponseInfo(22, "An error occurred during processing. Please try again in 5 minutes.") },
                { new ResponseInfo(23, "An error occurred during processing. Please try again in 5 minutes.") },
                { new ResponseInfo(24, "The Nova Bank Number or Terminal ID is incorrect. Call Merchant Service Provider.") },
                { new ResponseInfo(25, "An error occurred during processing. Please try again in 5 minutes.") },
                { new ResponseInfo(26, "An error occurred during processing. Please try again in 5 minutes.") },
                { new ResponseInfo(27, "The transaction resulted in an AVS mismatch. The address provided does not match billing address of cardholder.") },
                { new ResponseInfo(28, "The merchant does not accept this type of credit card.") },
                { new ResponseInfo(29, "The Paymentech identification numbers are incorrect. Call Merchant Service Provider.") },
                { new ResponseInfo(30, "The configuration with the processor is invalid. Call Merchant Service Provider.") },
                { new ResponseInfo(31, "The FDC Merchant ID or Terminal ID is incorrect. Call Merchant Service Provider.") },
                { new ResponseInfo(32, "This reason code is reserved or not applicable to this API.") },
                { new ResponseInfo(33, "FIELD cannot be left blank.") },
                { new ResponseInfo(34, "The VITAL identification numbers are incorrect. Call Merchant Service Provider.") },
                { new ResponseInfo(35, "An error occurred during processing. Call Merchant Service Provider.") },
                { new ResponseInfo(36, "The authorization was approved, but settlement failed.") },
                { new ResponseInfo(37, "The credit card number is invalid.") },
                { new ResponseInfo(38, "The Global Payment System identification numbers are incorrect. Call Merchant Service Provider.") },
                { new ResponseInfo(40, "This transaction must be encrypted.") },
                { new ResponseInfo(41, "This transaction has been declined.") },
                { new ResponseInfo(43, "The merchant was incorrectly set up at the processor. Call your Merchant Service Provider.") },
                { new ResponseInfo(44, "This transaction has been declined.") },
                { new ResponseInfo(45, "This transaction has been declined.") },
                { new ResponseInfo(46, "Your session has expired or does not exist. You must log in to continue working.") },
                { new ResponseInfo(47, "The amount requested for settlement cannot be greater than the original amount authorized.") },
                { new ResponseInfo(48, "This processor does not accept partial reversals.") },
                { new ResponseInfo(49, "A transaction amount greater than $[amount] will not be accepted.") },
                { new ResponseInfo(50, "This transaction is awaiting settlement and cannot be refunded. ") },
                { new ResponseInfo(51, "The sum of all credits against this transaction is greater than the original transaction amount.") },
                { new ResponseInfo(52, "The transaction was authorized, but the client could not be notified; the transaction will not be settled.") },
                { new ResponseInfo(53, "The transaction type was invalid for ACH transactions.") },
                { new ResponseInfo(54, "The referenced transaction does not meet the criteria for issuing a credit. ") },
                { new ResponseInfo(55, "The sum of credits against the referenced transaction would exceed the original debit amount.") },
                { new ResponseInfo(56, "This merchant accepts ACH transactions only; no credit card transactions are accepted. ") },
                { new ResponseInfo(57, "An error occurred in processing. Please try again in 5 minutes.") },
                { new ResponseInfo(58, "An error occurred in processing. Please try again in 5 minutes.") },
                { new ResponseInfo(59, "An error occurred in processing. Please try again in 5 minutes.") },
                { new ResponseInfo(60, "An error occurred in processing. Please try again in 5 minutes.") },
                { new ResponseInfo(61, "An error occurred in processing. Please try again in 5 minutes.") },
                { new ResponseInfo(62, "An error occurred in processing. Please try again in 5 minutes.") },
                { new ResponseInfo(63, "An error occurred in processing. Please try again in 5 minutes.") },
                { new ResponseInfo(65, "This transaction has been declined.") },
                { new ResponseInfo(66, "This transaction cannot be accepted for processing.") },
                { new ResponseInfo(68, "The version parameter is invalid.") },
                { new ResponseInfo(69, "The transaction type is invalid.") },
                { new ResponseInfo(70, "The transaction method is invalid.") },
                { new ResponseInfo(71, "The bank account type is invalid.") },
                { new ResponseInfo(72, "The authorization code is invalid.") },
                { new ResponseInfo(73, "The driver’s license date of birth is invalid.") },
                { new ResponseInfo(74, "The duty amount is invalid.") },
                { new ResponseInfo(75, "The freight amount is invalid.") },
                { new ResponseInfo(76, "The tax amount is invalid.") },
                { new ResponseInfo(77, "The SSN or tax ID is invalid.") },
                { new ResponseInfo(78, "The Card Code (CVV2/CVC2/CID) is invalid. ") },
                { new ResponseInfo(79, "The driver’s license number is invalid.") },
                { new ResponseInfo(80, "The driver’s license state is invalid.") },
                { new ResponseInfo(81, "The requested form type is invalid.") },
                { new ResponseInfo(82, "Scripts are only supported in version 2.5.") },
                { new ResponseInfo(83, "The requested script is either invalid or no longer supported.") },
                { new ResponseInfo(84, "This reason code is reserved or not applicable to this API.") },
                { new ResponseInfo(85, "This reason code is reserved or not applicable to this API.") },
                { new ResponseInfo(86, "This reason code is reserved or not applicable to this API.") },
                { new ResponseInfo(87, "This reason code is reserved or not applicable to this API.") },
                { new ResponseInfo(88, "This reason code is reserved or not applicable to this API.") },
                { new ResponseInfo(89, "This reason code is reserved or not applicable to this API.") },
                { new ResponseInfo(90, "This reason code is reserved or not applicable to this API.") },
                { new ResponseInfo(91, "Version 2.5 is no longer supported.") },
                { new ResponseInfo(92, "The gateway no longer supports the requested method of integration.") },
                { new ResponseInfo(97, "This transaction cannot be accepted.") },
                { new ResponseInfo(98, "This transaction cannot be accepted.") },
                { new ResponseInfo(99, "This transaction cannot be accepted.") },
                { new ResponseInfo(100, "The eCheck.Net type is invalid.") },
                { new ResponseInfo(101, "The given name on the account and/or the account type does not match the actual account.") },
                { new ResponseInfo(102, "This request cannot be accepted.") },
                { new ResponseInfo(103, "This transaction cannot be accepted.") },
                { new ResponseInfo(104, "This transaction is currently under review.") },
                { new ResponseInfo(105, "This transaction is currently under review.") },
                { new ResponseInfo(106, "This transaction is currently under review.") },
                { new ResponseInfo(107, "This transaction is currently under review.") },
                { new ResponseInfo(108, "This transaction is currently under review.") },
                { new ResponseInfo(109, "This transaction is currently under review.") },
                { new ResponseInfo(110, "This transaction is currently under review.") },
                { new ResponseInfo(116, "The authentication indicator is invalid.") },
                { new ResponseInfo(117, "The cardholder authentication value is invalid.") },
                { new ResponseInfo(118, "The combination of authentication indicator and cardholder authentication value is invalid.") },
                { new ResponseInfo(119, "Transactions having cardholder authentication values cannot be marked as recurring.") },
                { new ResponseInfo(120, "An error occurred during processing. Please try again.") },
                { new ResponseInfo(121, "An error occurred during processing. Please try again.") },
                { new ResponseInfo(122, "An error occurred during processing. Please try again.") },
                { new ResponseInfo(123, "This account has not been given the permission(s) required for this request.") },
                { new ResponseInfo(127, "The transaction resulted in an AVS mismatch. The address provided does not match billing address of cardholder.") },
                { new ResponseInfo(128, "This transaction cannot be processed.") },
                { new ResponseInfo(130, "This payment gateway account has been closed.") },
                { new ResponseInfo(131, "This transaction cannot be accepted at this time.") },
                { new ResponseInfo(132, "This transaction cannot be accepted at this time.") },
                { new ResponseInfo(141, "This transaction has been declined.") },
                { new ResponseInfo(145, "This transaction has been declined.") },
                { new ResponseInfo(152, "The transaction was authorized, but the client could not be notified; the transaction will not be settled.") },
                { new ResponseInfo(165, "This transaction has been declined.") },
                { new ResponseInfo(170, "An error occurred during processing. Please contact the merchant.") },
                { new ResponseInfo(171, "An error occurred during processing. Please contact the merchant.") },
                { new ResponseInfo(172, "An error occurred during processing. Please contact the merchant.") },
                { new ResponseInfo(173, "An error occurred during processing. Please contact the merchant.") },
                { new ResponseInfo(174, "The transaction type is invalid. Please contact the merchant.") },
                { new ResponseInfo(175, "The processor does not allow voiding of credits.") },
                { new ResponseInfo(180, "An error occurred during processing. Please try again.") },
                { new ResponseInfo(181, "An error occurred during processing. Please try again.") },
                { new ResponseInfo(185, "This reason code is reserved or not applicable to this API.") },
                { new ResponseInfo(193, "The transaction is currently under review.") },
                { new ResponseInfo(200, "This transaction has been declined.") },
                { new ResponseInfo(201, "This transaction has been declined.") },
                { new ResponseInfo(202, "This transaction has been declined.") },
                { new ResponseInfo(203, "This transaction has been declined.") },
                { new ResponseInfo(204, "This transaction has been declined.") },
                { new ResponseInfo(205, "This transaction has been declined.") },
                { new ResponseInfo(206, "This transaction has been declined.") },
                { new ResponseInfo(207, "This transaction has been declined.") },
                { new ResponseInfo(208, "This transaction has been declined.") },
                { new ResponseInfo(209, "This transaction has been declined.") },
                { new ResponseInfo(210, "This transaction has been declined.") },
                { new ResponseInfo(211, "This transaction has been declined.") },
                { new ResponseInfo(212, "This transaction has been declined.") },
                { new ResponseInfo(213, "This transaction has been declined.") },
                { new ResponseInfo(214, "This transaction has been declined.") },
                { new ResponseInfo(215, "This transaction has been declined.") },
                { new ResponseInfo(216, "This transaction has been declined.") },
                { new ResponseInfo(217, "This transaction has been declined.") },
                { new ResponseInfo(218, "This transaction has been declined.") },
                { new ResponseInfo(219, "This transaction has been declined.") },
                { new ResponseInfo(220, "This transaction has been declined.") },
                { new ResponseInfo(221, "This transaction has been declined.") },
                { new ResponseInfo(222, "This transaction has been declined.") },
                { new ResponseInfo(223, "This transaction has been declined.") },
                { new ResponseInfo(224, "This transaction has been declined.") },
                { new ResponseInfo(243, "Recurring billing is not allowed for this eCheck.Net type.") },
                { new ResponseInfo(244, "This eCheck.Net type is not allowed for this Bank Account Type.") },
                { new ResponseInfo(245, "This eCheck.Net type is not allowed when using the payment gateway hosted payment form.") },
                { new ResponseInfo(246, "This eCheck.Net type is not allowed.") },
                { new ResponseInfo(247, "This eCheck.Net type is not allowed.") },
                { new ResponseInfo(250, "This transaction has been declined.") },
                { new ResponseInfo(251, "This transaction has been declined.") },
                { new ResponseInfo(252, "Your order has been received. Thank you for your business!") },
                { new ResponseInfo(253, "Your order has been received. Thank you for your business!") },
                { new ResponseInfo(254, "Your transaction has been declined.") },
                { new ResponseInfo(261, "An error occurred during processing. Please try again.") },
                { new ResponseInfo(270, "The line item [item number] is invalid.") },
                { new ResponseInfo(271, "The number of line items submitted is not allowed. A maximum of 30 line items can be submitted.") },
                { new ResponseInfo(289, "This processor does not accept zero dollar authorization for this card type.") },
                { new ResponseInfo(290, "One or more required AVS values for zero dollar authorization were not submitted.") },
                { new ResponseInfo(295, "The amount of this request was only partially approved on the given prepaid card. Additional payments are required to complete the balance of this transaction.") },
                { new ResponseInfo(296, "The specified SplitTenderId is not valid.") },
                { new ResponseInfo(297, "A Transaction ID and a Split Tender ID cannot both be used in a single transaction request. ") },
                { new ResponseInfo(300, "The device ID is invalid.") },
                { new ResponseInfo(301, "The device batch ID is invalid.") },
                { new ResponseInfo(303, "The device batch is full. Please close the batch.") },
                { new ResponseInfo(304, "The original transaction is in a closed batch. ") },
                { new ResponseInfo(305, "The merchant is configured for auto-close. ") },
                { new ResponseInfo(306, "The batch is already closed. ") },
                { new ResponseInfo(307, "The reversal was processed successfully.") },
                { new ResponseInfo(308, "Original transaction for reversal not found. ") },
                { new ResponseInfo(309, "The device has been disabled. ") },
                { new ResponseInfo(310, "This transaction has already been voided. ") },
                { new ResponseInfo(311, "This transaction has already been captured") },
                { new ResponseInfo(315, "The credit card number is invalid.") },
                { new ResponseInfo(316, "The credit card expiration date is invalid.") },
                { new ResponseInfo(317, "The credit card has expired.") },
                { new ResponseInfo(318, "A duplicate transaction has been submitted. ") },
                { new ResponseInfo(319, "The transaction cannot be found.") }

            };
        }

        public ResponseInfo GetResponseInfoByResponseCode(int resonCode)
        {
            return ResponseInfoList.FirstOrDefault(responseInfo => responseInfo.ReasonCode == resonCode);
        }
    }

    public class ResponseInfo
    {
        public int ReasonCode;
        public string ReasonText;

        public ResponseInfo(int reasonCode, string reasonText)
        {
            ReasonCode = reasonCode;
            ReasonText = reasonText;
        }

        public string GetReasonText
        {
            get
            {
                return ReasonText;
            }
        }
        
    }
}

Open in new window

0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Windows Service with UDP 2 28
Round up to 100% in .NET 10 45
Get String split 5 33
Convert to Hour/minute textbox and compare 3 36
Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now