Create default config for each tenant in C# - c#

I have basic CRUD for a class ConfigSystem.
I have also two methods in the basic ConfigSystem Service.
public Type Get<Type>(string key, string userId)
{
//get config system
var configEntry = this.repository.GetSingleAsync(cs => cs.Key == key && cs.UserId == userId).Await();
if (configEntry == null)
{
configEntry = this.repository.GetSingleAsync(cs => cs.Key == key).Await();
}
if (typeof(Type).Name == configEntry.Type)
{
return JsonConvert.DeserializeObject<Type>(configEntry.Value);
//invalid config type exception
}
else
{
throw new InvalidCastException($"Cannot get the type of this particular key! ");
}
}
public async Task Set<T>(string key, string userId, T value)
{
CheckKey(key, userId);
// find key and then update its value
var configEntry = await this.repository.GetSingleAsync(cs => cs.Key == key && cs.UserId == userId);
//configEntry.Key = key;
if (configEntry == null)
{
configEntry = await this.repository.GetSingleAsync(cs => cs.Key == key);
}
configEntry.Type = value.GetType().Name;
configEntry.Value = JsonConvert.SerializeObject(value);
await this.repository.UpdateAsync(configEntry);
}
I have a static file Config:
public static Dictionary<string, object> ConfigurationList = new Dictionary<string, object>()
{
{"Currency", Enums.Currency.Lev },
{"Measure", Enums.Unit.LinearMetre },
{"DailyDraftLimit", 6},
{"DeleteDraftPeriod", 5},
{"NotificationStartTime", new TimeSpan(03, 00, 00) }, //give exact time 3AM.},
//TODO: Exclude weekends
{"NotificationPeriod", 24},//24 hours
{"PaymentNotificationPeriod", 24},
{"PaymentReceivers", null}, //what do I put here? if I dont have the ids/ -> we put null if we are not sure about the info or the info is not static!
{"VisitsNotificationPeriod", 24},
{"VisitsInternalReceivers", null},
{"VisitsExternalReceivers", null},
{"TermsNotificationPeriod", 24},
{"TermsReceivers", null }
}
and this is my ConfigSystem class:
public class ConfigSystem : AuditEntity<long>
{
/// <summary>
/// Gets or sets the key.
/// </summary>
public string Key { get; set; }
/// <summary>
/// Gets or sets the type.
/// </summary>
public string Type { get; set; }
/// <summary>
/// Gets or sets the value.
/// </summary>
public string Value { get; set; }
/// <summary>
/// Gets or sets the user identifier.
/// </summary>
public string UserId { get; set; }
}
This is my method in the Startup.
private void CreateDefaultConfig(ApplicationDbContext context, IServiceScope serviceScope)
{
var defaultConfig = DefaultTenantConfig.ConfigurationList;
if (context.ConfigSystems.Count() == 0)
{
var configSystemService = serviceScope.ServiceProvider.GetRequiredService<IConfigSystemService>();
//foreach (var entry in defaultConfig)
//{
// var entityToSaveInDb = configSystemService.CreateAsync()
//}
//create for each record a config system entry in the database
}
//check if in the context of the database there are no configs
}
I have no idea what to do with the object, but I had to keep it in object because I had different type of entries. I need to create them for each tenant and it is a default config if they are not created in the database.

Related

Using Reflection to create extensible charts for a website

I’m trying to implement a website where new charts can be added by just dropping a DLL into folder. At the time of writing it is not clear what charts are going to be needed and this provides a simple way of deploying new charts without having to redeploy the website in its entirety. I’m using Google Charts to provide the Google functionality and each chart will be displayed
Each type of chart inherits from the following Interface
public enum ChartType
{
BAR,
COLUMN,
PIE,
TABLE
}
public class DataColumn
{
public String ColumnType { get; set; }
public String ColumnValue { get; set; }
}
public interface IChart
{
/// <summary>
/// Dictionary of Columns, Each column is defined as a type and title
/// </summary>
List<DataColumn> Columns { get; set; }
/// <summary>
/// ChartType, What type of Chart; possible values BAR, COLUMN, PIE, TABLE
/// </summary>
ChartType ChartType { get; }
/// <summary>
/// Data - data for the chart
/// </summary>
String Data { get; }
/// <summary>
/// Name of the chart, must be unique used to identify each chart stub
/// </summary>
String Name { get; }
/// <summary>
/// Title - the title that will be displayed above the chart
/// </summary>
String Title { get; }
/// <summary>
/// What position will the legend of there is one.
/// </summary>
String LegendPosition { get; }
}
The following uses the above interface
public class ReferralDownloadCount : IChart, IDisposable
{
List<ChartDemo.DataColumn> columns = null;
public ReferralDownloadCount()
{
columns = new List<ChartDemo.DataColumn>()
{
new ChartDemo.DataColumn() { ColumnType = "String" , ColumnValue = "Date" },
new ChartDemo.DataColumn() { ColumnType = "Number" , ColumnValue = "Referral Count"}
};
}
/// <summary>
/// Returns the chart data
/// </summary>
public String Data
{
get
{
String sql = String.Empty;
String jsonResult = String.Empty;
DataSet ds = null;
DataTable dt = null;
List<ReferralCountData> results = null;
JsonSerializer serializer = null;
try
{
sql = "Select * From[Portal].[ReferralCount] Where DATEDIFF(d, [Download Date], Convert(Date, GETDATE())) < 8 Order By[Download Date] Asc";
ds = DataToolbox.Execute(new SqlConnection(Properties.Settings.Default.DataConnection), sql, CommandType.Text);
if (ds.Tables.Count > 0)
{
dt = ds.Tables[0]; // we really are only expecting one table
results = new List<ReferralCountData>();
serializer = new JsonSerializer();
serializer.Converters.Add(new JavaScriptDateTimeConverter());
foreach ( DataRow dr in dt.Rows)
{
using (ReferralCountData rcd = new ReferralCountData()
{
Label = ((System.DateTime)dr.ItemArray[0]).ToString("dd/MM/yyyy"),
Value = Convert.ToInt32(dr["Referral Count"])
})
{
results.Add(rcd);
}
}
jsonResult = JsonConvert.SerializeObject(results);
}
}
catch ( System.Exception ex)
{
throw ex;
}
finally
{
}
return jsonResult;
}
}
public List<ChartDemo.DataColumn> Columns {
get
{
return columns;
}
set
{
columns = value;
}
}
public ChartType ChartType => ChartType.COLUMN;
public string Name => "REFERRALCOUNT";
public string Title => "Referral Download Count";
public string LegendPosition => "None";
public void Dispose()
{
}
}
The site traverses a directory containing DLLs, and searches for any classes such as the one above to create Charts
Classes which have inherited from IChart are then extracted as each DLL is checked by GetChartPlugins
static List<IChart> GetChartPlugins(List<Assembly> assemblies)
{
List<Type> availableTypes = new List<Type>();
List<Type> alertList = null;
try
{
foreach (Assembly currentAssembly in assemblies)
availableTypes.AddRange(currentAssembly.GetTypes());
alertList = availableTypes.FindAll(delegate (Type t)
{
List<Type> interfaceTypes = new List<Type>(t.GetInterfaces());
return interfaceTypes.Contains(typeof(IChart));
});
}
catch (ReflectionTypeLoadException ex)
{
StringBuilder sb = new StringBuilder();
foreach (Exception exSub in ex.LoaderExceptions)
{
sb.AppendLine(exSub.Message);
FileNotFoundException exFileNotFound = exSub as FileNotFoundException;
if (exFileNotFound != null)
{
if (!string.IsNullOrEmpty(exFileNotFound.FusionLog))
{
sb.AppendLine("Fusion Log:");
sb.AppendLine(exFileNotFound.FusionLog);
}
}
sb.AppendLine();
}
string errorMessage = sb.ToString();
}
catch ( System.Exception ex)
{
throw ex;
}
finally
{
}
// convert the list of Objects to an instantiated list of ICalculators
return alertList.ConvertAll<IChart>(delegate (Type t) { return Activator.CreateInstance(t) as IChart; });
}
However when this runs the attempt to Call currentAssembly.GetTypes() falls over throwing a ReflectionTypeLoadException
Which eventually becomes;
Method 'get_Columns' in type 'ReferralManagementCharts.ReferralDownloadCount' from assembly 'ReferralManagementCharts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
Can anyone see why since the Columns property of ReferralDownlodCount
public List<ChartDemo.DataColumn> Columns {
get
{
return columns;
}
set
{
columns = value;
}
}
Does have a get.

Using dynamic linq extensions with jqgrid on one to many relationships

Im not sure if the title of the question is correct if not let me know and i will change it. Okay so firstly im using jgrid in a asp.net application. I have a helper that sets up the page size, rows and does the sorting. The issue is i can only sort on parameters for the current table it does not work when the parameter name is from a separate table connected through a relationship.
The linq extension is for orderBy and thenBy, they both take a string parameter and sort order parameter. I have tried setting the string parameter as "WaterSample.Name", watersample being another table from a relationship and name a parameter in that table but unfortunately i cannot do it this way in c# since i am using an anonymous type. So my question is can i make the line extensions search through the relationships to find match the property name. Sorry if this is a bit confusing im still fairly new to linq.
i have included the class below that contains the extensions.
namespace Helpers
{
[ModelBinder(typeof(GridModelBinder))]
[Serializable]
public class JqGridSettings
{
public int PageIndex { get; set; }
public int PageSize { get; set; }
public string SortColumn { get; set; }
public string SortOrder { get; set; }
public string SortColumn2 { get; set; }
public string SortOrder2 { get; set; }
public string SortColumn3 { get; set; }
public string SortOrder3 { get; set; }
public JqGridSettings()
{
}
/// <summary>
/// Initializes a new instance of the GridSettings class.
/// </summary>
/// <param name="stringData">The string that represents the a GridSettings object.</param>
public JqGridSettings(string stringData)
{
var tempArray = stringData.Split(new[] { "#;" }, StringSplitOptions.None);
PageSize = int.Parse(tempArray[0]);
PageIndex = int.Parse(tempArray[1]);
SortColumn = tempArray[2];
SortOrder = tempArray[3];
}
/// <summary>
/// Build a string used to cache the current GridSettings object.
/// </summary>
/// <returns>A string that represents the current GridSettings object.</returns>
public override string ToString()
{
return string.Format("{0}#;{1}#;{2}#;{3}", PageSize, PageIndex, SortColumn,SortOrder);
}
public IQueryable<T> LoadGridData<T>(IQueryable<T> dataSource, out int count)
{
var query = dataSource;
//
// Sorting and Paging by using the current grid settings.
//
query = query.OrderBy<T>(SortColumn, SortOrder);
if (String.IsNullOrEmpty(SortColumn2) == false)
{
query = query.ThenBy<T>(SortColumn2, SortOrder2);
}
if (String.IsNullOrEmpty(SortColumn3) == false)
{
query = query.ThenBy<T>(SortColumn3, SortOrder3);
}
count = query.Count();
//
if (PageIndex < 1)
PageIndex = 1;
//
var data = query.Skip((PageIndex - 1) * PageSize).Take(PageSize);
return data;
}
}
public static class LinqExtensions
{
public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string sortColumn, string direction)
{
var methodName = string.Format("OrderBy{0}", direction.ToLower() == "asc" ? "" : "descending");
var parameter = Expression.Parameter(query.ElementType, "p");
var memberAccess = sortColumn.Split('.').Aggregate<string, MemberExpression>(null, (current, property) => Expression.Property(current ?? (parameter as Expression), property));
var orderByLambda = Expression.Lambda(memberAccess, parameter);
var result = Expression.Call(typeof(Queryable),methodName,new[]{query.ElementType, memberAccess.Type},query.Expression,Expression.Quote(orderByLambda));
return query.Provider.CreateQuery<T>(result);
}
public static IQueryable<T> ThenBy<T>(this IQueryable<T> query, string sortColumn, string direction)
{
var methodName = string.Format("ThenBy{0}", direction.ToLower() == "asc" ? "" : "descending");
var parameter = Expression.Parameter(query.ElementType, "p");
var memberAccess = sortColumn.Split('.').Aggregate<string, MemberExpression>(null, (current, property) => Expression.Property(current ?? (parameter as Expression), property));
var orderByLambda = Expression.Lambda(memberAccess, parameter);
var result = Expression.Call(typeof(Queryable), methodName, new[] { query.ElementType, memberAccess.Type }, query.Expression, Expression.Quote(orderByLambda));
return query.Provider.CreateQuery<T>(result);
}
}
public class GridModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
try
{
var request = controllerContext.HttpContext.Request;
return new JqGridSettings
{
PageIndex = int.Parse(request["page"] ?? "1"),
PageSize = int.Parse(request["rows"] ?? "50"),
SortColumn = request["sidx"] ?? "",
SortOrder = request["sord"] ?? "asc",
};
}
catch
{
//
// For unexpected errors use the default settings!
//
return null;
}
}
}
}
Thank you for any help or suggestions.

Getting description of Enum and using this as text property of dropdownlist in MVC?

I have a dropdown control inside my view. Now i want it to have Description of enum as it's text. I am least worried about Id but i need text to be well formatted.
Refer the following code.
public static List<EnumModel> GetEnumList<T>()
{
var enumValues = Enum.GetValues(typeof(T)).Cast<T>().Select(rentalType => new EnumModel()
{
Value = Convert.ToInt32(rentalType),
Name = GetDisplayName<T>(rentalType, false)
}).ToList();
return enumValues;
}
public static string GetDisplayName<T>(T value, bool isDisplayName)
{
if (value == null)
{
throw new ArgumentNullException("value", "Enum value Empty");
}
var type = value.GetType();
var field = type.GetField(value.ToString());
if (field == null)
{
return value.ToString();
}
var attributes = ((DisplayAttribute[])field.GetCustomAttributes(typeof(DisplayAttribute), false)).FirstOrDefault();
return attributes != null ? isDisplayName == true ? attributes.GetDescription() : attributes.Description : value.ToString();
}
public class EnumModel
{
/// <summary>
/// Gets or sets the value
/// </summary>
public int Value { get; set; }
/// <summary>
/// Gets or sets the name
/// </summary>
public string Name { get; set; }
}
You can get List<EnumModel> as ENUM list with name and value.What you need to do is just make a List<SelectListitem> from List<EnumModel>
Hope this helps.
Use this code and bind with your dropdown-
public static List<SelectListItem> GetSelectList(Type enumType, String SelectedValue, Boolean IsValString = true)
{
Array values = Enum.GetValues(enumType);
List<SelectListItem> selectListItems = new List<SelectListItem>(values.Length);
foreach (var i in Enum.GetValues(enumType))
{
String name = Enum.GetName(enumType, i);
String desc = name;
FieldInfo fi = enumType.GetField(name);
var attributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
String result = attributes.Length == 0 ? desc : ((DescriptionAttribute)attributes[0]).Description;
var selectItem = new SelectListItem()
{
Text = result,
Value = (IsValString) ? i.ToString() : ((Int32)i).ToString()
};
if ((SelectedValue != null) && (SelectedValue.Equals(selectItem.Value)))
{
selectItem.Selected = true;
}
selectListItems.Add(selectItem);
}
return selectListItems;
}

How Can I Pass a Complex Class Object to a Web API Using C#

I need to pass complex or List<> class object to a web API in C#, without AJAX or jQuery. This is my code I used for the API and controller.
Web API:
[AcceptVerbs("GET", "POST")]
[HttpGet]
public void WriteBusinessObjectApiFromObj(int Pa1, string Pa2, object item)
{
// To Do In Function
}
Controller:
public void WriteBusinessObjectApi(object obj)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:8080/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var apiUrl = "api/WriteBusinessObjectApiFromObj?Pa1=1&Pa2=2";
var response = client.PostAsJsonAsync(apiUrl, obj).Result;
client.Dispose();
if (response.IsSuccessStatusCode)
{
}
}
}
I try to call the API but I can't send objects to it.
This object I try to send like:
Returned list of object from this function:
public List<Product> GetProductsObj()
{
var products = new List<Product>
{
new Product()
{
Id = 4,
Name = "product 4",
SupProducts = new List<SupProduct>
{
new SupProduct()
{
Id = 41,
Name = "Sup 41"
},
new SupProduct()
{
Id = 42,
Name = "Sup 42"
},
new SupProduct()
{
Id = 43,
Name = "Sup 43"
}
}
},
new Product()
{
Id = 5,
Name = "product 5",
SupProducts = new List<SupProduct>
{
new SupProduct()
{
Id = 51,
Name = "Sup 51"
},
new SupProduct()
{
Id = 52,
Name = "Sup 52"
},
new SupProduct()
{
Id = 53,
Name = "Sup 53"
}
}
},
new Product()
{
Id = 6,
Name = "product 6",
SupProducts = new List<SupProduct>
{
new SupProduct()
{
Id = 71,
Name = "Sup 71"
},
new SupProduct()
{
Id = 72,
Name = "Sup 72"
},
new SupProduct()
{
Id = 73,
Name = "Sup 73"
}
}
}
};
return products;
}
It's possible that the binder is getting confused and trying to incorrectly mix FromBody and FromURI so try wrapping all of the parameters in an object instead. This is a better pattern anyway because you're explicitly stating what it is that makes a "request". Note also that in the below I specify the object type rather than just saying "object". Better to be explicit, you know the Type on both sides anyway!
public class WriteBusinessObjectApiFromObjRequest
{
public int Pa1 { get; set; }
public string Pa2 { get; set; }
public List<Product> Item { get; set; } // change to your Type
}
[AcceptVerbs("GET", "POST")]
[HttpGet]
public void WriteBusinessObjectApiFromObj(WriteBusinessObjectApiFromObjRequest request)
{
// To Do In Function
}
var apiUrl = "api/WriteBusinessObjectApiFromObj";
var response = client.PostAsJsonAsync(
apiUrl,
new WriteBusinessObjectApiFromObj { Pa1 = 1, Pa2 = "2", Item = obj })
.Result;
Here is a cool overview of how to use parameter binding that doesn't go into any technical detail. Alternatively, here is a much more in depth exploration of Web API parameter binding
Model:
public class Employee
{
[Required]
public string EmployeeId { get; set; }
public string EmployeeName { get; set; }
public int EmployeeRollNum { get; set; }
public EmployeeAddress EmployeeAddr { get; set; }
public List<EmployeeAddress> AllEmployeeAddr { get; set; }
}
public class EmployeeAddress
{
//[Required]
public string EmployeeAddressId { get; set; }
public string EmployeeAddressName { get; set; }
public List<int> AllNum { get; set; }
}
In Web API Server:
[HttpGet]
public object Get([FromUri]Employee employee)
{
if (employee != null && ModelState.IsValid)
{
// Do something with the product (not shown).
return employee;
}
return employee;
}
In Web Api Client:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace WebApiConsoleApplication1
{
public static class UrlHelpers
{
/// <summary>
/// To the query string. http://ole.michelsen.dk/blog/serialize-object-into-a-query-string-with-reflection.html
/// </summary>
/// <param name="request"> The request. </param>
/// <param name="separator"> The separator. </param>
/// <returns></returns>
/// <exception cref="System.ArgumentNullException"> request </exception>
public static string ToQueryString(this object request, string innerPropertyName = null, string separator = ",")
{
if (request == null)
{
throw new ArgumentNullException("request");
}
StringBuilder propertyQuery = new StringBuilder();
// Get all primitive properties on the object
var properties = request.GetType().GetProperties()
.Where(x => x.CanRead)
.Where(x => x.GetValue(request, null) != null)
.Where(x => !x.PropertyType.IsClass || (x.PropertyType.IsClass && x.PropertyType.FullName == "System.String"))
.ToDictionary(x => x.Name, x => x.GetValue(request, null));
foreach (KeyValuePair<string, object> kvp in properties)
{
if (string.IsNullOrEmpty(innerPropertyName))
{
propertyQuery.AppendFormat("{0}={1}", Uri.EscapeDataString(kvp.Key), Uri.EscapeDataString(kvp.Value.ToString()));
}
else
{
propertyQuery.AppendFormat("{0}.{1}={2}", Uri.EscapeDataString(innerPropertyName), Uri.EscapeDataString(kvp.Key), Uri.EscapeDataString(kvp.Value.ToString()));
}
propertyQuery.AppendFormat("&");
}
var innerClass = request.GetType().GetProperties()
.Where(x => x.CanRead)
.Where(x => x.GetValue(request, null) != null && x.PropertyType.IsClass && x.PropertyType.FullName != "System.String" && !(x.GetValue(request, null) is IEnumerable))
.ToDictionary(x => x.Name, x => x.GetValue(request, null));
// Get names for all IEnumerable properties (excl. string)
var propertyCollectionNames = request.GetType().GetProperties()
.Where(x => x.CanRead)
.Where(x => x.GetValue(request, null) != null)
.ToDictionary(x => x.Name, x => x.GetValue(request, null))
.Where(x => !(x.Value is string) && x.Value is IEnumerable)
.ToDictionary(x => x.Key, x => x.Value);
// Concat all IEnumerable properties into a comma separated string
foreach (var kvp in propertyCollectionNames)
{
var valueType = kvp.Value.GetType();
var valueElemType = valueType.IsGenericType
? valueType.GetGenericArguments()[0]
: valueType.GetElementType();
if (valueElemType.IsPrimitive || valueElemType == typeof(string)) // List of primitive value type or string
{
var enumerable = kvp.Value as IEnumerable;
int count = 0;
foreach (object obj in enumerable)
{
if (string.IsNullOrEmpty(innerPropertyName))
{
propertyQuery.AppendFormat("{0}[{1}]={2}", Uri.EscapeDataString(kvp.Key), count, Uri.EscapeDataString(obj.ToString()));
}
else
{
propertyQuery.AppendFormat("{0}.{1}[{2}]={3}", Uri.EscapeDataString(innerPropertyName), Uri.EscapeDataString(kvp.Key), count, Uri.EscapeDataString(obj.ToString()));
}
count++;
propertyQuery.AppendFormat("&");
}
}
else if (valueElemType.IsClass) // list of class Objects
{
int count = 0;
foreach (var className in kvp.Value as IEnumerable)
{
string queryKey = string.Format("{0}[{1}]", kvp.Key, count);
propertyQuery.AppendFormat(ToQueryString(className, queryKey));
count++;
}
}
}
foreach (var className in innerClass)
{
propertyQuery.AppendFormat(ToQueryString(className.Value, className.Key));
}
return propertyQuery.ToString();
}
}
public class Employee
{
public string EmployeeId { get; set; }
public string EmployeeName { get; set; }
public int EmployeeRollNum { get; set; }
public EmployeeAddress EmployeeAddr { get; set; }
public List<EmployeeAddress> AllEmployeeAddr { get; set; }
}
public class EmployeeAddress
{
//[Required]
public string EmployeeAddressId { get; set; }
public string EmployeeAddressName { get; set; }
public List<int> AllNum { get; set; }
}
internal class Program
{
private static void Main()
{
RunAsync().Wait();
Console.WriteLine("Completed");
Console.ReadLine();
}
private static async Task RunAsync()
{
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(ConfigurationManager.AppSettings.Get("HostURL"));
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(ConfigurationManager.AppSettings.Get("AcceptType")));
HttpResponseMessage response = await client.GetAsync("api/Values/1");
if (response.IsSuccessStatusCode)
{
string val = await response.Content.ReadAsAsync<string>();
Console.WriteLine("{0}\t", val);
}
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(ConfigurationManager.AppSettings.Get("AcceptType")));
//client.DefaultRequestHeaders.Add()
// HTTP GET
Employee emp = new Employee();
emp.EmployeeId = "sri1";
emp.AllEmployeeAddr = new List<EmployeeAddress>();
EmployeeAddress lstemployeeAddr = new EmployeeAddress();
lstemployeeAddr.EmployeeAddressId = "Address1";
lstemployeeAddr.AllNum = new List<int>();
lstemployeeAddr.AllNum.Add(1);
lstemployeeAddr.AllNum.Add(2);
lstemployeeAddr.AllNum.Add(3);
emp.AllEmployeeAddr.Add(lstemployeeAddr);
lstemployeeAddr = new EmployeeAddress();
lstemployeeAddr.EmployeeAddressId = "Address2";
lstemployeeAddr.AllNum = new List<int>();
lstemployeeAddr.AllNum.Add(24);
lstemployeeAddr.AllNum.Add(56);
emp.AllEmployeeAddr.Add(lstemployeeAddr);
EmployeeAddress innerEmployeeAddr = new EmployeeAddress();
innerEmployeeAddr.EmployeeAddressId = "Addr3";
innerEmployeeAddr.AllNum = new List<int>();
innerEmployeeAddr.AllNum.Add(5);
innerEmployeeAddr.AllNum.Add(6);
emp.EmployeeAddr = innerEmployeeAddr;
string query = emp.ToQueryString();
response = await client.GetAsync("api/Values?" + query);
if (response.IsSuccessStatusCode)
{
Employee product = await response.Content.ReadAsAsync<Employee>();
Console.WriteLine("{0}\t{1}\t", product.EmployeeId, product.EmployeeName);
}
}
}
catch (Exception ex)
{
}
}
}
}

Logging state of object. Getting all its property values as string

public class Address
{
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
}
......
var emp1Address = new Address();
emp1Address.AddressLine1 = "Microsoft Corporation";
emp1Address.AddressLine2 = "One Microsoft Way";
emp1Address.City = "Redmond";
emp1Address.State = "WA";
emp1Address.Zip = "98052-6399";
Consider above class and later its initialization. Now at some point I want to log its state when error occurs. I would like to get the string log somewhat like below.
string toLog = Helper.GetLogFor(emp1Address);
sting toLog should look something like below.
AddressLine1 = "Microsoft Corporation";
AddressLine2 = "One Microsoft Way";
City = "Redmond";
State = "WA";
Zip = "98052-6399";
And then I will log toLog string.
How can I access all the property names and property values of an object within Helper.GetLogFor() method?
Solution that I implemented:-
/// <summary>
/// Creates a string of all property value pair in the provided object instance
/// </summary>
/// <param name="objectToGetStateOf"></param>
/// <exception cref="ArgumentException"></exception>
/// <returns></returns>
public static string GetLogFor(object objectToGetStateOf)
{
if (objectToGetStateOf == null)
{
const string PARAMETER_NAME = "objectToGetStateOf";
throw new ArgumentException(string.Format("Parameter {0} cannot be null", PARAMETER_NAME), PARAMETER_NAME);
}
var builder = new StringBuilder();
foreach (var property in objectToGetStateOf.GetType().GetProperties())
{
object value = property.GetValue(objectToGetStateOf, null);
builder.Append(property.Name)
.Append(" = ")
.Append((value ?? "null"))
.AppendLine();
}
return builder.ToString();
}
public static string GetLogFor(object target)
{
var properties =
from property in target.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
select new
{
Name = property.Name,
Value = property.GetValue(target, null)
};
var builder = new StringBuilder();
foreach(var property in properties)
{
builder
.Append(property.Name)
.Append(" = ")
.Append(property.Value)
.AppendLine();
}
return builder.ToString();
}
static void Log(object #object)
{
foreach (var property in #object.GetType().GetProperties())
Console.WriteLine(property.Name + ": " + property.GetValue(#object, null).ToString());
}
You can access the property name using reflection
like following
Type t = emp1Address.GetType();
PropertyInfo [] pi = t.GetProperties();
foreach (PropertyInfo p in pi)
{
//You can get the value (using GetValue() method) and name (p.Name) here.
}

Categories