In a .NET Core 6 RestAPI application, I'm tracking global stock exchanges and have an instance of the below Exchange class called "ex".
public class Exchange
{
public string CountryCode { get; set; }
public string Currency { get; set; }
public string DataSourceCode { get; set; }
public int DaysHoursId { get; set; }
public string ExchangeCode { get; set; }
public string ExchangeName { get; set; }
public int Id { get; set; }
public bool IsActive { get; set; }
public DateTimeOffset LastUpdatedDate { get; set; }
public string LastUpdatedStatus { get; set; }
public DateTimeOffset NextUpdateDateTime { get; set; }
public string Region { get; set; }
public string Timezone { get; set; }
public string Type { get; set; }
public string Url { get; set; }
public string Website { get; set; }
}
All fields are populated with non-null data. In this case, the body of my Postman call is:
{
"CountryCode": "USA",
"Currency": "USD",
"DataSourceCode": "IA2",
"DaysHoursId": 2,
"ExchangeCode": "AMEX",
"ExchangeName": "AMEX",
"IsActive": true,
"LastUpdatedDate": "2022-04-24T15:42:28.2533333+00:00",
"LastUpdatedStatus": "OK",
"NextUpdateDateTime": "2022-04-24T15:42:28.2533333+00:00",
"Region": "NORTH AMERICA",
"Timezone": "EST",
"Type": "STOCK",
"Url": "https://www.nyse.com/markets/nyse-american",
"Website": "www.AMEX.com"
}
Using Reflection, I create a DataTable from this object with all columns except for "Id", which is an Identity primary key in the table to which data will be loaded, as follows:
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(ex);
DataTable dt = new DataTable();
foreach (PropertyDescriptor p in props)
{
if (p.Name != "Id") // insert into an identity column not allowed.
{
dt.Columns.Add(p.Name, p.PropertyType);
}
}
I then attempt to create a row in the dt datatable, as follows:
DataRow dr = dt.NewRow();
Type t = ex.GetType();
for (int i = 0; i <= dt.Columns.Count; i++)
{
t.InvokeMember(dt.Columns[i].ColumnName, System.Reflection.BindingFlags.SetProperty, null, ex, new object[] { dt.Columns[i].ColumnName });
}
... which, when executed and traced, InvokeMember successfully iterated through the CountryCode, Currency, and DataSourceCode columns, but then - when it reaches DaysHoursId - threw a "System.MissingMethodException: 'Method MarketApi.Core.Entitites.Exchange.DaysHoursId' not found' exception.
Any insight as to what I'm doing wrong would be very much appreciated!
It throws for DaysHoursId because it is the first non-string Property of your class Exchange. The problem is that you set the property names also as their values.
Works for CountryCode, Currency, DataSourceCode, that expect each a string value. But crashes on DaysHoursId. The binder looks for a string property setter method of name/signature
set_DaysHoursId(string)
which actually doesn't exist.You rather want to assign the values in that loop: