I have a class:
public class LotInfo
{
public string lotn { get; set; }
public string imlitm { get; set; }
public string imdsc { get; set; }
public string wplotn { get; set; }
public int wptrdj { get; set; }
public DateTime wptrdj_d { get; set; }
public string wplitm { get; set; }
public int wptrqt { get; set; }
public string wpkyfn { get; set; }
public int wpdoco { get; set; }
public string iolitm { get; set; }
public string iodcto { get; set; }
public int iodoco { get; set; }
public int ioub04 { get; set; }
}
I have 2 instances.
Object1 and Object2
I want to inject object2 -> object1 for specific properties.
So i have overridden the Match method like this:
public class LotInfoInject : ConventionInjection
{
protected override bool Match(ConventionInfo c)
{
return c.SourceProp.Name.StartsWith("io");
}
}
and i am using the injecter like this:
object1.InjectFrom(object2);
I cant figure out why i am getting the exception.
{"Object of type 'System.String' cannot be converted to type
'System.Int32'."}
If i DONT override the Match method it works but i am getting properties that i dont want replaced from object1
any ideas?
You're trying to put iolitm (string) in iodoco (int).
Try like this:
public class LotInfoInject : ConventionInjection
{
protected override bool Match(ConventionInfo c)
{
return c.SourceProp.Name.StartsWith("io")
&& c.SourceProp.Name == c.TargetProp.Name;
}
}
Related
public class 2500113075262000 {
public string pair { get; set; }
public string type { get; set; }
public double amount { get; set; }
public int rate { get; set; }
public string timestamp_created { get; set; }
public int status { get; set; }
}
public class Return {
public 2500113075262000 2500113075262000 { get; set; }
}
public class Root {
public int success { get; set; }
public Return #return { get; set; }
}
class 2500113075262000 is constantly changing, this is the order ID, like deserialize
{"success":1,"return":{"2500113075262000":{"pair":"eth_rur","type":"sell","amount":0.00110569,"rate":46100,"timestamp_created":"1608918997","status":0}}}
It looks like it's only the key - presumably the order ID - which is changing. I would suggest removing your Return class entirely, and changing your Root class to have a Dictionary<string, Order>. I'd also suggest writing your classes with idiomatic .NET property names, and using JsonPropertyAttribute to specify the representation in the JSON. So it would be something like this:
public class Order
{
[JsonProperty("pair")]
public string Pair { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
// etc, other properties
}
public class Root
{
[JsonProperty("success")]
public int Success { get; set; }
[JsonProperty("return")]
public Dictionary<string, Order> Returns { get; set; }
}
I get a JSON response like this :
{
"xpubaddressONE":{"final_balance":123,"n_tx":0,"total_received":0},
"xpubaddressTWO":{"final_balance":25221,"n_tx":0,"total_received":0},
"xpubaddressTHREE":{"final_balance":1123,"n_tx":0,"total_received":0}
}
I want to deserialize it into C# object. I need to build classes like this :
public class xpubaddressONE
{
public int final_balance { get; set; }
public int n_tx { get; set; }
public int total_received { get; set; }
}
public class xpubaddressTHREE
{
public int final_balance { get; set; }
public int n_tx { get; set; }
public int total_received { get; set; }
}
public class xpubaddressTWO
{
public int final_balance { get; set; }
public int n_tx { get; set; }
public int total_received { get; set; }
}
public class RootObject
{
public xpubaddressONE one { get; set; }
public xpubaddressTWO two { get; set; }
public xpubaddressTHREE three { get; set; }
}
My goal is to remove additional classes(xpubaddressONE,xpubaddressTWO,xpubaddressTHREE) and access objects like this :
RootObject.final_balance
I would try deserializing a Dictionary<string, xpubaddress>, where xpubaddress is:
public class xpubaddress
{
public int final_balance { get; set; }
public int n_tx { get; set; }
public int total_received { get; set; }
}
This should then give you a dictionary with 3 keys that you can inspect with foreach, TryGetValue, etc.
Alternatively, stick with your root type, but share the inner type:
public class xpubaddress
{
public int final_balance { get; set; }
public int n_tx { get; set; }
public int total_received { get; set; }
}
public class RootObject
{
public xpubaddress xpubaddressONE{ get; set; }
public xpubaddress xpubaddressTWO{ get; set; }
public xpubaddress xpubaddressTHREE { get; set; }
}
You may also find it easier to leave the property names as idiomatic .NET names, and use [JsonProperty] or [DataMember] to rename them, i.e.
[JsonProperty("final_balance")]
public int FinalBalance { get; set; }
You can introduce the single xpubaddress class, like
public class xpubaddress
{
public int final_balance { get; set; }
public int n_tx { get; set; }
public int total_received { get; set; }
}
and then deserialize it into IDictionary<string, xpubaddress> for example, add access objects using the xpubaddressONE, xpubaddressTWO, etc., keys
var result = JsonConvert.DeserializeObject<IDictionary<string, xpubaddress>>(json);
var balance = result?["xpubaddressONE"]?.final_balance ?? 0;
In my CollectionService class i want to be able to use either DatabaseWatchService or RemoteFilesWatchService therefore I used IWatchService<IEntity> watchService parameter which should be common for both. Nevertheless in DoIt() when i try to use either one of the class i am having following error:
Cannot implicitly convert type 'RemoteFilesWatchService' to
'IWatchService'. An explicit conversion exists (are you missing a
cast?)
How to fix that to able to use in CollectionService either one mentioned class or another.
This is the full code:
public interface IWatch
{
void Watch();
}
public interface IWatchService<TDataEntity> where TDataEntity : IEntity
{
INotificationFactory NotificationFactory { get; }
ObservableCollection<TDataEntity> MatchingEntries { get; set; }
}
public interface IDatabaseWatchService<TDataEntity> : IWatchService<TDataEntity> where TDataEntity : IDatabaseEntity
{
IDatabaseRepository<IDbManager> DatabaseRepository { get; }
}
public interface IRemoteFilesWatchService<TDataEntity> : IWatchService<TDataEntity> where TDataEntity : IFileEntity
{
List<string> ExistingRemoteFiles { get; set; }
List<RemoteLocation> RemoteLocations { get; set; }
IWinScpOperations RemoteManager { get; set; }
IRemoteFilesRepository<IDbManager, TDataEntity> RemoteFilesRepository { get; }
}
public class RemoteFilesWatchService : IRemoteFilesWatchService<IFileEntity>, IWatch
{
public INotificationFactory NotificationFactory { get; }
public ObservableCollection<IFileEntity> MatchingEntries { get; set; }
public List<string> ExistingRemoteFiles { get; set; }
public List<RemoteLocation> RemoteLocations { get; set; }
public IWinScpOperations RemoteManager { get; set; }
public IRemoteFilesRepository<IDbManager, IFileEntity> RemoteFilesRepository { get; }
public RemoteFilesWatchService(IWinScpOperations remoteOperator,
IRemoteFilesRepository<IDbManager, IFileEntity> remoteFilesRepository,
INotificationFactory notificationFactory)
{
RemoteManager = remoteOperator;
RemoteFilesRepository = remoteFilesRepository; //csv, xml or other repo could be injected
NotificationFactory = notificationFactory;
}
public void Watch()
{
}
}
public class DatabaseWatchService : IDatabaseWatchService<DatabaseQuery>, IWatch
{
public INotificationFactory NotificationFactory { get; }
public ObservableCollection<DatabaseQuery> MatchingEntries { get; set; }
public IDatabaseRepository<IDbManager> DatabaseRepository { get; }
public DatabaseWatchService(IDatabaseRepository<IDbManager> databaseRepository,
INotificationFactory notificationFactory)
{
DatabaseRepository = databaseRepository;
NotificationFactory = notificationFactory;
}
public void Watch()
{
}
}
public class CollectionService
{
private IWatchService<IEntity> _watchService;
public CollectionService(IWatchService<IEntity> watchService)
{
_watchService = watchService;
}
}
class Run
{
void DoIt()
{
IWatchService<IEntity> fileWatcherServiceCsv = new RemoteFilesWatchService(new WinScpOperations(),
new RemoteCsvFilesRepository(new DbManager(ConnectionDbType.MySql)),
new NotificationFactory());
var coll1 = new CollectionService(fileWatcherServiceCsv);
}
}
public interface IEntity
{
}
public interface IFileEntity : IEntity
{
int Id { get; set; }
string Name { get; set; }
bool IsActive { get; set; }
bool RemoveFromSource { get; set; }
string DestinationFolder { get; set; }
RemoteLocation RemoteLocation { get; set; }
}
public interface IDatabaseEntity : IEntity
{
}
public class CsvFile : IFileEntity
{
public int ColumnHeader { get; set; }
public int ColumnsCount { get; set; }
public string Separator { get; set; }
public int ValuesRowStartposition { get; set; }
public int ColumnRowPosition { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
public bool RemoveFromSource { get; set; }
public string DestinationFolder { get; set; }
public RemoteLocation RemoteLocation { get; set; }
}
public class XmlFile : IFileEntity
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
public bool RemoveFromSource { get; set; }
public string DestinationFolder { get; set; }
public RemoteLocation RemoteLocation { get; set; }
public string SubNode { get; set; }
public string MainNode { get; set; }
}
Rather than having IWatchService expose a concrete type, I'd suggest instead having it require reimplementation of those interfaces from ObservableCollection that you actually want the consumers to use (or move those onto another interface and have that be what MatchingEntries returns).
Here I've guessed that the consumers want the events that the observable collection raises and to be able to enumerate the collection and that's all, which means we can a) implement those interfaces and b) make the interface covariant:
public interface IWatchService<out TDataEntity> :
INotifyCollectionChanged,
INotifyPropertyChanged,
IEnumerable<TDataEntity>
where TDataEntity : IEntity
{
INotificationFactory NotificationFactory { get; }
}
Now, if the implementations choose to use an ObservableCollection and just use simple wrappers to implement those interfaces or choose to satisfy the interface in some other way has been move back into an implementation decision.
I have classes those are strongly bound with the ASP.NET MVC view.
Against their fields/properties ( columns ), I have to generate a unique name using Guid.NewGuid(). In this way, every time view would open , there would be new unique name against every control which is associated with specific field/column inside that class.
But, I would like to skip some of the properties while generating unique name. Because, those properties are either hidden inputs or place holders for other specific purpose. What could be the nice way? Should I apply custom attribute for this? During iteration of fields, I would simply skip those fields.
For example the class is "
public abstract class DashboardModuleCommonSettings
{
public int ForwarderId { get; set; }
public int ClientSubsidiaryId { get; set; }
public bool IsContentUpdateable { get; set; }
public int? AfterTime { get; set; }
public string Title { get; set; }
[Not Required to be iterated for generating unique name]
public string ModuleSettingsPopupName { get; set; }
[Not Required to be iterated for generating unique name]
public int ClientId { get; set; }
[Not Required to be iterated for generating unique name]
[HiddenInput(DisplayValue = false)]
public string CurrentLayout { get; set; }
}
How can I achieve this?
Here is a full example of how you would use it:
[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public class NotRequiredForUniqueNameAttribute : Attribute { }
The NotRequiredForUniqueNameAttribute is applied to the properties that you don't want to use, so your class becomes:
public abstract class DashboardModuleCommonSettings
{
public int ForwarderId { get; set; }
public int ClientSubsidiaryId { get; set; }
public bool IsContentUpdateable { get; set; }
public int? AfterTime { get; set; }
public string Title { get; set; }
[NotRequiredForUniqueName]
public string ModuleSettingsPopupName { get; set; }
[NotRequiredForUniqueName]
public int ClientId { get; set; }
[NotRequiredForUniqueName]
[HiddenInput(DisplayValue = false)]
public string CurrentLayout { get; set; }
}
Then later when you want to extract the properties that do not have that attribute, you can do something like this:
public class TestClass
{
public static string GenerateUniqueName(DashboardModuleCommonSettings dmcs)
{
var propInfos = dmcs.GetType().GetProperties(
BindingFlags.Instance | BindingFlags.Public).Where(
p => p.GetCustomAttribute<NotRequiredForUniqueNameAttribute>() == null);
string uniqueName = "";
foreach (var propInfo in propInfos)
{
//Do something with the property info
}
return uniqueName;
}
}
One of the possible ways to do so is to define your custom attribute and ignore a property if it has one assigned.
public sealed class SkipPropertyAttribute: Attribute
{
}
And on your class:
public abstract class DashboardModuleCommonSettings
{
public int ForwarderId { get; set; }
public int ClientSubsidiaryId { get; set; }
public bool IsContentUpdateable { get; set; }
public int? AfterTime { get; set; }
public string Title { get; set; }
[SkipProperty]
public string ModuleSettingsPopupName { get; set; }
[SkipProperty]
public int ClientId { get; set; }
[SkipProperty]
[HiddenInput(DisplayValue = false)]
public string CurrentLayout { get; set; }
}
You can use the Attribute.IsDefined method to find out if attribute is defined.
For posterity, here's the dirty version without flags.
public abstract class DashboardModuleCommonSettings
{
public int ForwarderId { get; set; }
public int ClientSubsidiaryId { get; set; }
public bool IsContentUpdateable { get; set; }
public int? AfterTime { get; set; }
public string Title { get; set; }
public string __marker__ { get; }
public string ModuleSettingsPopupName { get; set; }
public int ClientId { get; set; }
public string CurrentLayout { get; set; }
}
public static class Extractor
{
public static IEnumerable<PropertyInfo> VisibleProperties<T>()
{
foreach (var p in typeof(T).GetProperties())
{
if ("__marker__".Equals(p.Name, StringComparison.InvariantCultureIgnoreCase)) yield break;
yield return p;
}
}
}
I want to create a class that have a class but this second class may be different each time the first class is called. For example:
public class ServerResponseObject
{
public string statusCode { get; set; }
public string errorCode { get; set; }
public string errorDescription { get; set; }
public Object obj { get; set; }
public ServerResponseObject(Object obje)
{
obj = obje;
}
}
public class TVChannelObject
{
public string number { get; set; }
public string title { get; set; }
public string FavoriteChannel { get; set; }
public string description { get; set; }
public string packageid { get; set; }
public string format { get; set; }
}
public class ChannelCategoryObject
{
public string id { get; set; }
public string name { get; set; }
}
How can I do it to call the ServerResponseObject with different objects each time, once with TVChannelObject and once with ChannelCategoryObject?
What you're looking for is a generic type parameter:
public class ServerResponseObject<T>
{
public ServerResponseObject(T obj)
{
Obj = obj;
}
public T Obj { get; set; }
}