How do I get theses values from this dictionary - c#

I'm using mastercard API. Link https://developer.mastercard.com/documentation/mastercom/6#api_transactions_debit_master_card_and_europe_dual_acquirer
I Have to get the value of these keys. (These are key from Dictionary List)
transactionSummaryList[0].authTransactionId
transactionSummaryList[0].clearingTransactionId
transactionSummaryList[0].singleMessageSummaryDetails.authTransaction.acquirerReferenceNumber
transactionSummaryList[0].singleMessageSummaryDetails.authTransaction.adviceReasonCode
...
My code so far
try
{
TransactionsDebitMasterCardAndEuropeDualAcquirer response = TransactionsDebitMasterCardAndEuropeDualAcquirer.searchForDebitMCMessageTransaction(transactionsValues);
OutputTransaction outputTransaction = new OutputTransaction();
foreach (Dictionary<String, Object> item in (List<Dictionary<String, Object>>)response["transactionSummaryList"])
{
TransactionSummary transactionSummary = new TransactionSummary();
transactionSummary.authTransactionId = Out(item, "authTransactionId").ToString();
transactionSummary.clearingTransactionId = Out(item, "clearingTransactionId").ToString();
Object aux = Out(item, "singleMessageSummaryDetails");
outputTransaction.transactionSummaryLists.Add(transactionSummary);
}
outputTransactions.Add(outputTransaction);
}
public static Object Out(Dictionary<String, Object> response, String key)
{
return response[key];
}
I'm facing trouble when i try to get values from singleMessageSummaryDetails Key.
All values that I want is inside Object aux, but i can't "reach" them.

You have case aux as an Object, therefore it doesn't know about any specific properties. Object is the base class that all other .NET classes inherit from.
If you want to get to a specific property they you'll need to cast your object to a specific type.
If you know the class type, then you can cast it directly using either;
public static YourClass Out(Dictionary<String, YourClass > response, String key) or MyClass myClassInstance = (YourClass)myObject;
If you don't know the type then you can use reflection. Its a bit more complicated but will be something like;
Type myType = myObject.GetType();
IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());
foreach (PropertyInfo prop in props)
{
object propValue = prop.GetValue(myObject, null);
// Do something with propValue
}

I finally got it!
To make this work, first I turn the mastercard answer in a JSON.
Them I put it simple and easy in my object (DeserializeObject).
try
{
TransactionsDebitMasterCardAndEuropeDualAcquirer response = TransactionsDebitMasterCardAndEuropeDualAcquirer.searchForDebitMCMessageTransaction(transactionsValues);
OutputTransaction outputTransaction = new OutputTransaction();
var aux = JsonConvert.SerializeObject(response);
outputTransaction = JsonConvert.DeserializeObject<OutputTransaction>(aux);
outputTransactions.Add(outputTransaction);
}
Thanks so much for your answer #Mark Cooper, helps me a lot.
Sry for my bad english.
Thanks again.

Related

How to use the properties of a passed list of known objects

this might be a simple fix but I can't seem to find anything about it. I am very new to C# if it's not obvious.
I'm passing a list of objects from my main method but I haven't been able to use the properties of the objects. I want to use a property called "Asset" This is my code:
private void GetDueDates(List<object> objects)
{
Type myType = objects.GetType();
IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());
if(props.Contains(Asset)
{
doStuff();
}
}
I thought if I got the type of object then I could use the correct property but that didn't work. Do I even need to find which type it is?
Asset isn't a valid expression here, unless you've actually got a variable called Asset somewhere. You want to find out if the name of any property is Asset... and you want to do it on each object, not on the list itself:
foreach (var item in objects)
{
var props = item.GetType().GetProperties();
var assetProperty = props.FirstOrDefault(p => p.Name == "Asset");
if (assetProperty != null)
{
var value = assetProperty.GetValue(item, null);
// Do stuff...
}
}
Alternatively, if you're only looking for a public property, you can pass the name to GetProperty:
foreach (var item in objects)
{
var assetProperty = item.GetType().GetProperty("Asset");
if (assetProperty != null)
{
var value = assetProperty.GetValue(item, null);
// Do stuff...
}
}
Having said this, it would be cleaner if you had an interface or something similar:
var assetItems = objects.OfType<IHasAsset>();
foreach (var assetItem in assetItems)
{
var asset = assetItem.Asset;
...
}
If you know what type all of the objects in objects should be, then objects should be a list of that type, instead of a list of object (so List<MyType>). At this point, you can simply refer to objects[0].Asset, since all of the objects in the list are of type MyType.
If you still want objects to be a List<object>, then you'll have to typecast each of the objects in the list to a MyType in order to use the Asset property of the MyType class: ((MyType)objects[0]).Asset.
If you do this, and you aren't sure that all of the objects in the list are actually of type MyType, you need to check that:
if (objects[0] is MyType)
{
// do stuff with ((MyType)objects[0]).Asset
}

How to iterate properties of two objects dynamically

I have two object of same class, I want to update the p2 with fields which are are in Dirty list. So far I managed to write the following code but struggling to get the value of p1 properties. What object should I pass here as parameter to GetValue method.
Person p1 = new Person();
p1.FirstName = "Test";
Person p2 = new Person();
var allDirtyFields = p1.GetAllDirtyFields();
foreach (var dirtyField in allDirtyFields)
{
p2.GetType()
.GetProperty(dirtyField)
.SetValue(p1.GetType().GetProperty(dirtyField).GetValue());
}
_context.UpdateObject(p2);
_context.SaveChanges();
Thanks in advance.
You should try that:
foreach (var dirtyField in allDirtyFields)
{
var prop = p2.GetType().GetProperty(dirtyField);
prop.SetValue(p2, prop.GetValue(p1));
}
It is a better to store PropertyInfo instance in a variable, then trying to resolve it twice.
Did you know that you don't need to retrieve the property for each object?
Type metadata is common to any object of the whole type.
For example:
// Firstly, get dirty property informations!
IEnumerable<PropertyInfo> dirtyProperties = p2.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where
(
property => allDirtyFields.Any
(
field => property.Name == field
)
);
// Then, just iterate the whole property informations, but give the
// "obj" GetValue/SetValue first argument the references "p2" or "p1" as follows:
foreach(PropertyInfo dirtyProperty in dirtyProperties)
{
dirtyProperty.SetValue(p2, dirtyProperty.GetValue(p1));
}
Check that the first parameter of PropertyInfo.GetValue(...) and PropertyInfo.SetValue(...) is the object for which you want to get or set the value of the whole property.
In each iteration, you have to get a reference to the PropertyInfo. When you call it's SetValue method, you should pass in 2 parameters, the object for which you will set the property and the actual value you are setting. For the latter one, you should invoke the GetValue method on the same property, passing in the p1 object as parameter, i.e. the source for the value.
Try this:
foreach (var dirtyField in allDirtyFields)
{
var p = p2.GetType().GetProperty(dirtyField);
p.SetValue(p2, p.GetValue(p1));
}
I would recommend you to keep the dirtyField variables in a dictionary and retrieve the associated PropertyInfo object from this dictionary. It should be much faster.
Firstly, declare some static variable in your class:
static Dictionary<string, PropertyInfo>
personProps = new Dictionary<string, PropertyInfo>();
Then you may change your method to:
foreach (var dirtyField in allDirtyFields)
{
PropertyInfo p = null;
if (!personProps.ContainsKey(dirtyField))
{
p = p2.GetType().GetProperty(dirtyField);
personProps.Add(dirtyField, p);
}
else
{
p = personProps[dirtyField];
}
p.SetValue(p2, p.GetValue(p1));
}
You need to pass the instance from which you want to get the property value, like so:
p1.GetType().GetProperty(dirtyField).GetValue(p1, null)
The second parameter, can be used to retrieve a value at a certain index if the property type is indexed.
IIrc you send p1 being the instance that holds the value and null to indicate you're not searching for a specific index value.

Looping though a dictionary containing objects

I have the following loop over a dictionary type collection
foreach(KeyValuePair<Vector2, Object> entry in v_map.map_set)
{
}
I want to access the object properties, but the expected syntax doesn't work. E.G:
foreach(KeyValuePair<Vector2, Object> entry in v_map.map_set)
{
Object ob = entry.Value;
ob.property;
}
Fails because C# can't find the property wanted.
So, how do I access the desired properties?
solution:
foreach(KeyValuePair<Vector2, Object> entry in v_map.map_set)
{
if (entry.Value is warehouse)
{
warehouse ob = (warehouse)entry.Value;
}
}
If you know the type of the objects that are in the KeyValuePair, you can cast it to that type, and you will be able to find the properties you need.
And if you have several different objects stored, you can check which type it is by using is.
Like so:
if(entry.Value is Foo)
{
Foo lFoo = (Foo)entry.Value;
}
else if(entry.Value is Bar)
{
Bar lBar = (Bar)entry.Value;
}
You can make use of Refection to get the value of proerty of the object.
something like this
PropertyInfo info2 = object.GetType().GetProperty("prpertyname");
Object val = info2.GetValue(object, null);
You need to cast entry.Value to the type you need. The Object type itself isn't going to expose the properties you want.
If you just need to access the values, and you know the expected type you can use
foreach(ExpectedType value in v_map.map_set.Values.OfType<ExpectedType>())
{
var property = value.Property;
}
where Property is a property on ExpectedType.
The problem is that you're using an object which isn't typed. So you're going to need to use reflection like this:
PropertyInfo pi = ob.GetType().GetProperty("PropertyName");
var val = pi.GetValue(ob, null);
Now, if the property isn't public then you'll need to employ something else like this:
PropertyInfo pi = ob.GetType().GetProperty("PropertyName", BindingFlags.Instance | BindingFlags.NonPublic);
var val = pi.GetValue(ob, null);
Now, if this is actually a field you're trying to get to, you're going to need to do something different even yet:
FieldInfo fi = ob.GetType().GetField("fieldName");
var val = fi.GetValue(ob);
GetProperty method
BindingFlags enumeration
GetField method

set property type dynamically in c#

I got the following problem with my data stream:
The data stream consists of a dictionary, which I want to parse and specify the type of the value dynamically.
I.e. my data strea includes:
"date", "01.01.2000"
"name", "joe"
"alive", "true"
"health", "100"
Now I would like to set my properties of a generic class according to this data stream:
class GenericClass
{
Hashtable genericAttributes;
}
Is there a possibility to set my values of the data stream to the correct type via reflection?
I could try something like:
DateTime.TryParse(date, out myDate);
for the date time object, but I don't think this will work when trying to parse doubles, floats, int16s, int32s, uint16,...
Some thoughts on that?
Thx and regards
My guess from your question is that they all are IConvertible, so I would do something my code example below. The idea is that I specify the "want"-order, ie in the order I want the types if they can fit multiple types, and then I try to convert them in that order.
public class GenericPropClass
{
public Type type;
public object value;
public string key;
}
[TestMethod]
public void PropertySet()
{
var dict = new Dictionary<string, string>();
var resultingList = new List<GenericPropClass>();
// Specify the order with most "specific"/"wanted" type first and string last
var order = new Type[] { typeof(DateTime), typeof(int), typeof(double), typeof(string) };
foreach (var key in dict.Keys)
foreach (var t in order)
{
try
{
var res = new GenericPropClass()
{
value = Convert.ChangeType(dict[key], t),
key = key,
type = t,
};
resultingList.Add(res);
break;
}
catch (Exception)
{
// Just continue
}
}
}
Sorry for a short answer containing almost only code, I might have time to improve it tonight to get my thoughts in, but I have to go now :)

Get value of a specific object property in C# without knowing the class behind

I have an object (.NET) of type "object". I don't know the "real type (class)" behind it during runtime , but I know, that the object has a property "string name". How can I retrive the value of "name"? Is this possible?
something like this:
object item = AnyFunction(....);
string value = item.name;
Use reflection
System.Reflection.PropertyInfo pi = item.GetType().GetProperty("name");
String name = (String)(pi.GetValue(item, null));
You can do it using dynamic instead of object:
dynamic item = AnyFunction(....);
string value = item.name;
Note that the Dynamic Language Runtime (DLR) has built-in caching mechanisms, so subsequent calls are very fast.
Reflection can help you.
var someObject;
var propertyName = "PropertyWhichValueYouWantToKnow";
var propertyName = someObject.GetType().GetProperty(propertyName).GetValue(someObject, null);
Reflection and dynamic value access are correct solutions to this question but are quite slow.
If your want something faster then you can create dynamic method using expressions:
object value = GetValue();
string propertyName = "MyProperty";
var parameter = Expression.Parameter(typeof(object));
var cast = Expression.Convert(parameter, value.GetType());
var propertyGetter = Expression.Property(cast, propertyName);
var castResult = Expression.Convert(propertyGetter, typeof(object));//for boxing
var propertyRetriver = Expression.Lambda<Func<object, object>>(castResult, parameter).Compile();
var retrivedPropertyValue = propertyRetriver(value);
This way is faster if you cache created functions. For instance in dictionary where key would be the actual type of object assuming that property name is not changing or some combination of type and property name.
In some cases, Reflection doesn't work properly.
You could use dictionaries, if all item types are the same.
For instance, if your items are strings :
Dictionary<string, string> response = JsonConvert.DeserializeObject<Dictionary<string, string>>(item);
Or ints:
Dictionary<string, int> response = JsonConvert.DeserializeObject<Dictionary<string, int>>(item);
You can do it using dynamic instead of object:
dynamic item = AnyFunction(....);
string value = item["name"].Value;
Simply try this for all properties of an object,
foreach (var prop in myobject.GetType().GetProperties(BindingFlags.Public|BindingFlags.Instance))
{
var propertyName = prop.Name;
var propertyValue = myobject.GetType().GetProperty(propertyName).GetValue(myobject, null);
//Debug.Print(prop.Name);
//Debug.Print(Functions.convertNullableToString(propertyValue));
Debug.Print(string.Format("Property Name={0} , Value={1}", prop.Name, Functions.convertNullableToString(propertyValue)));
}
NOTE: Functions.convertNullableToString() is custom function using for convert NULL value into string.empty.

Categories