I am using FileHelpers to create NACHA files. Example below
Many of the properties are numeric with leading zeros so they have been defined as strings. Is there an attribute that can pad the leading zeros in the Class property, similar to the way FieldTrim/TrimMode works to remove whitespace?
[FixedLengthRecord()]
public class FileControlRecord
{
[FieldFixedLength(1)]
public int RecordTypeCode = 9; //Constant
[FieldFixedLength(6)]
public string BatchCount; //Numeric
[FieldFixedLength(6)]
public string BlockCount; //Numeric
[FieldFixedLength(8)]
public string EntryAddendaCount; //Numeric
[FieldFixedLength(10)]
public string EntryHash; //Numeric
[FieldFixedLength(12)]
public string TotalDebit; //$$$$$$$$$$cc
[FieldFixedLength(12)]
public string TotalCredit; //$$$$$$$$$$cc
[FieldFixedLength(39)]
[FieldNotInFile]
public string RESERVED; //Blank
}
You must use FieldAlign with the padding char:
[FixedLengthRecord()]
public class FileControlRecord
{
[FieldFixedLength(1)]
public int RecordTypeCode = 9; //Constant
[FieldFixedLength(6)]
public string BatchCount; //Numeric
[FieldFixedLength(6)]
public string BlockCount; //Numeric
[FieldFixedLength(8)]
public string EntryAddendaCount; //Numeric
[FieldFixedLength(10)]
public string EntryHash; //Numeric
[FieldFixedLength(12)]
[FieldAlign(AlignMode.Right, '$')]
public string TotalDebit; //$$$$$$$$$$cc
[FieldFixedLength(12)]
[FieldAlign(AlignMode.Right, '$')]
public string TotalCredit; //$$$$$$$$$$cc
[FieldFixedLength(39)]
public string RESERVED; //Blank
}
PS: I recomend you to use the last version of the library:
https://github.com/MarcosMeli/FileHelpers/releases/latest
or via NuGet https://www.nuget.org/packages/FileHelpers/
Related
I have the following models
public class CustomEvent
{
private string _tag;
public int Id { get; set; }
public int PId { get; set; }
public DateTimeOffset TimeStamp { get; set; }
public string Mentor { get; set; }
public string Type { get; set; }
public string Tag
{
get => _tag;
set
{
_tag = GetTagTypeList.GetTagType(typeof(TagType)).Contains(value) ? value : "Unspecified";
}
}
}
public static class TagType
{
public const string Unspecified = "Unspecified";
public const string AmxPersonalItemCreate = "Amx.PersonalItem.Create";
public const string AmxPersonalItemUpdate = "Amx.PersonalItem.Update";
public const string AmxPersonalItemDelete = "Amx.PersonalItem.Delete";
public const string AmxRegionCreate = "Amx.Region.Create";
public const string AmxRegionUpdate = "Amx.Region.Delete";
public const string AmxRegionDelete = "Amx.Region.Update";
}
public class GetTagTypeList
{
public static List<String> GetTagType(Type type)
{
return type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
.Select(x=>x.GetValue(null).ToString()).ToList();
}
}
The above code restricts the setter to the list of static values. However this is very inefficient, as it is reflecting over the class every single time the method [GetTagType] is called.
I now have a requirement to Create a TagType class with a private constructor, and static values.
Given the values to be expressed have "." in them, it will require a custom json serializer as well.
I have read somewhere that a solution could be to use nested classes to get values which match the string being created.
i.e. for "Amx.PersonalItem.Create" we could create a class which resemble:
public static class Amx
{
public static class PersonalItem
{
public static TagType Create { get; } = new TagType("Amx.PersonalItem.Create");
}
}
I need to integrate the above example into my CustomEvent Class.
Or any other solution that uses static values to achieve same result.
Would appreciate any help ?
How about making a static item in the class that builds the list and stores it in a static variable? That means you can build the list once no matter how many times your setter is called. You still have to search the list but you don't need to use reflection.
I have a following JSON response:
{
"data": [
{
"ac_conditions": "[{\"ac_condition_group_id\":156570,\"ac_condition_group_name\":\"\u0413\u0440\u0443\u043f\u043f\u0430 \u0443\u0441\u043b\u043e\u0432\u0438\u0439 1\",\"id\":311790,\"ac_parameter\":\"utm_source\",\"ac_operator\":\"=\",\"value\":\"google_rem\",\"is_negative\":false},{\"ac_condition_group_id\":156570,\"ac_condition_group_name\":\"\u0413\u0440\u0443\u043f\u043f\u0430 \u0443\u0441\u043b\u043e\u0432\u0438\u0439 1\",\"id\":275094,\"ac_parameter\":\"utm_source\",\"ac_operator\":\"=\",\"value\":\"yandex_retargeting\",\"is_negative\":false}]",
"is_dt_enabled": true,
"ac_id": 162866,
"site_blocks": "[{\"id\":324164,\"name\":\"\u041d\u043e\u043c\u0435\u0440 1 \u043d\u0430 \u0441\u0430\u0439\u0442\u0435\",\"phone_type\":\"virtual\",\"numb\":\"74950238629\",\"forward_numb\":null,\"is_dt_enabled\":true,\"dt_number_pool_numbers\":[\"74951828912\",\"74950324045\",\"74950324046\",\"74950324043\",\"74950324037\",\"74951828907\",\"74950324048\",\"74950324049\",\"74951523589\",\"74953239984\"]}]"
}
],
"success": true
}
I create a class to deserealize it
public class Condition
{
public bool success;
public List<Data> data;
public class Data
{
public string ac_conditions;
public int ac_id;
public bool is_dt_enabled;
public string site_blocks;
};
}
It's working fine. What I need is to deserealize also the elements ac_conditions and site_blocks. I have created a new class but I get an exception (System.String cannot cast to List)
public class Condition
{
public bool success;
public List<Data> data;
public class Data
{
public List<ConditionCamp> ac_conditions;
public int ac_id;
public bool is_dt_enabled;
public List<SiteBlock> site_blocks;
public class ConditionCamp
{
public int ac_condition_group_id;
public string ac_condition_group_name;
public int id;
public string ac_parameter;
public string ac_operator;
public string value;
public bool is_negative;
}
public class SiteBlock
{
public int id;
public string name;
public string phone_type;
public string numb;
public string forward_numb;
public bool is_dt_enabled;
public string dt_number_pool_numbers;
}
};
}
I use this line in my code to deserialize the JSON response
JsonConvert.DeserializeObject<Models.Condition>(string_Condition);
Your JSON property "site_blocks" is a string value containing serialized JSON-data. Therefore you need a second step to unwrap/deserialize the data. If you can change the the way how the response is generated you can fix it there (return JSON in site_blocks and no string)
E.g. (using Json.net and results of second parse run are store in site_blocks_parsed)
public class Condition
{
public bool success;
public List<Data> data;
public class Data
{
public string ac_conditions;
public int ac_id;
public bool is_dt_enabled;
public string site_blocks;
public List<SiteBlock> site_blocks_parsed;
public class ConditionCamp
{
public int ac_condition_group_id;
public string ac_condition_group_name;
public int id;
public string ac_parameter;
public string ac_operator;
public string value;
public bool is_negative;
}
public class SiteBlock
{
public int id;
public string name;
public string phone_type;
public string numb;
public string forward_numb;
public bool is_dt_enabled;
public string dt_number_pool_numbers;
}
};
}
...
var condition = JsonConvert.DeserializeObject<Condition>(jsonString);
foreach (var data in condition.data) {
data.site_blocks_parsed = JsonConvert.DeserializeObject<List<SiteBlock>>(data.site_blocks);
}
I have a class as:
public class PersianDate
{
public int Year;
public int Month;
public int Day;
public int Hour;
public int Minute;
public int Second;
public string MonthName;
}
I want that if I convert it like here:
HTools.PersianDate pDate=new HTools.PersianDate();
string date = pDate.ToString();
And I want date to be:
1396-06-14T19:17:38
How can I do that?
public class PersianDate
{
public int Year;
public int Month;
public int Day;
public int Hour;
public int Minute;
public int Second;
public string MonthName;
public override string ToString()
{
return string.Format("{0}-{1}-{2}T{3}:{4}:{5}",Year,Month,Day,Hour,Minute,Second);
}
}
Override ToString() method from object class to get the format you want.
DotNetFiddle Example.
If you want a string that represent the object as a json you can use the "Newtonsift.Json" Nuget package:
PersianDate thing = new PersianDate();
//TODO: fill you thing with the data you need
string json = JsonConvert.SerializeObject(thing);
If you want specific string - ovverride the ToString methods in your class:
public override string ToString()
{
return $"{Year}-{Month}-{Day}T{Hour}:{Minute}:{Second}";
}
I duplicated a Class1 in a Class2 with the same properties but not all ones. In my context, I have a Class1 obj (o1) initialised with values and I want to change some ones with values of a Class2 obj (o2) without losing the o1 data (values which aren't in o2). Manually, I need to reassignate o1 with values of o2 so I would like to find an automatic way like mapping the classes.
Classes:
public class Class1
{
public bool Property1;
public int Property2;
public string Property3;
public bool Property4;
public int Property5;
public string Property6;
public bool Property7;
public int Property8;
public string Property9;
public bool Property10;
public int Property11;
public string Property12;
public bool Property13;
public int Property14;
public string Property15;
public bool Property16;
public int Property17;
public string Property18;
public bool Property19;
public int Property20;
}
public class Class2
{
public bool Property1;
public int Property2;
public string Property3;
public bool Property7;
public int Property8;
public string Property9;
public bool Property10;
public int Property11;
public string Property12;
public bool Property13;
public int Property14;
public string Property15;
public bool Property16;
public int Property17;
public string Property18;
public bool Property19;
public int Property20;
public Class1 ToClass1()
{
return new Class1()
{
Property1 = Property1,
Property2 = Property2,
Property3 = Property3,
Property7 = Property7,
...
Property20 = Property20
};
}
}
If I do ToClass1(), I lose the values of Property4, Property5 and Property6 of the o1.
What I do now:
// o1 and o2 are initialised with values.
o1.Property1 = o2.Property1;
o1.Property2 = o2.Property2;
o1.Property3 = o2.Property3;
o1.Property7 = o2.Property7;
...
o1.Property20 = o2.Property20;
you need to use automapper and configure your mapping rule to ignore the properties you wont want to map.
Look at this link
I have the following class:
[Serializable]
public class SerialAssassin
{
public Hero hero;
public Point heroPB;
public Boss boss;
public Point bossPB;
public Attack attack;
public Point attackPB;
public HPMeter bossHP;
public Point bossHPPB;
public PPMeter heroPP;
public Point heroPPPB;
public Rectangle bossRect;
public Rectangle attackRect;
public int heroState;
public int stepRate;
public int attackDirection;
public int attackLoop;
public int contadorPaso;
public int contadorPasoBoss;
public int bossTop, bossLeft;
public int bossState;
public int bossHealth;
public int bossHPCap;
public int opa;
public int battlesWon;
public int mainBossCounter;
public int ppleft;
public bool paso;
public bool inStadium;
public bool fading;
public bool fightingMainBoss;
public bool fainted;
public string currentPokemon;
}
I'm having problems reading the data from the XML, which was written as follows:
XmlSerializer serializer = new XmlSerializer(typeof(SerialAssassin));
TextWriter textWriter = new StreamWriter(#"..\..\Resources\saveState.xml");
serializer.Serialize(textWriter, serial);
textWriter.Close();
From there, I don't quite know how to read the data. Plus the fact that the XML doesn't serialize the objects of Hero, Boss, Attack, HPMeter, PPMeter.
Hero class:
public class Hero
{
int state = 0;
int x, y;
string path;
Image img;
//methods
}
I'd be grateful if you would be so kind as to explain to me how to load those objects/primitives and then use them.
IIRC, the XmlSerializer checks for properties, not fields. (I think it can use public fields, but you really ought to switch to properties anyway) In addition, classes do not need to be marked as Serializable. (Serializable is used for others such as binary and SOAP serializers)
Replace your fields with properties with public getters and setters. In addition, make sure your other classes (such as Hero, Point, Boss) are all also serializable according to XmlSerializer's rules:
public class SerialAssassin
{
public Hero hero { get; set; }
public Point heroPB { get; set; }
public Boss boss { get; set; }
public int heroState { get; set; }
...
To deserialize, use its Deserialize method (http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.deserialize.aspx):
Stream xmlInputStream = ... //get your file stream, or TextReader, or XmlReader
XmlSerializer deserializer = new XmlSerializer(typeof(SerialAssassin));
SerialAssassin assassin = (SerialAssassin)deserializer.Deserialize(xmlInputStream)
EDIT: Looking at your sample Hero class, it's not serializing any of its values because you have declared them all to be private. Make them public instead.
public class Hero
{
public int state {get; set; }
public int x { get; set; }
public int y { get; set; }
public string path { get; set; }
[XmlIgnore]
public Image img { get; set; }
}
I suspect that Image will not be serializable, so you may want to store the image's file path (or some other identifying information) so you can save/load it. [XmlIgnore] will instruct the XmlSerializer to ignore that property so it doesn't fail during serialization/deserialization.
XmlSerializer serializer = new XmlSerializer(typeof(SerialAssassin));
SerialAssassin assassin;
using(var reader = File.OpenText(#"..\..\Resources\saveState.xml"))
{
assassin = (SerialAssassin)serializer.Deserialize(reader);
}