C# parse textual file in a specific format - c#

I have never done something like this so I'm really curious on how this can be performed. I imagine it can be either done via regex or in c# somehow...
I have a textual file with data in following format:
12.23.45.56:8080:username:password
12.23.45.56:8080:username:password
12.23.45.56:8080:username:password
12.23.45.56:8080:username:password
I have prepared a class which looks like following:
public class ParsedData
(
public string IP { get; set; }
public string Port { get; set; }
public string Username { get; set; }
public string Password { get; set; }
)
The desired output how I would like it to be is that I can parse each line individually and 1 line should have the data stored in a parsed object (list of ParsedData);
How could do this, and to parse the each line of data individually ?
Can someone help me out ?
var completedList = text.Split(':').Select(pr => new ParsedData
{
IP = pr.ElementAt(0).ToString() // this should be the IP But I'm getting the
// Index was outside the bounds of the array. exception in this part
/*My elements here*/
}).ToList();

It looks like at least one row doesn't have any data in it, maybe there is an empty row in the input data?
Try printing out each row of data before selecting the first element of the array - then you can see which input is causing the exception.

You may use Regex (.+?):(.+?):(.+?):(.+), here example:
using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;
namespace Main {
public struct ParsedData {
public string IP { get; set; }
public string Port { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
class Prog {
static List<ParsedData> pdl = new List<ParsedData>();
static string file = #"12.23.425.56:90:kukur:psiar%4
151.23.255.52:3131:Zandga:Ikurit
52.23.45.56:5125:Ningame:Mirsga!#
112.223.45.56:4000:Bisgo:One0ne";
static void Main() {
var re = new Regex(#"(.+?):(.+?):(.+?):(.+)");
foreach (Match m in re.Matches(file)) {
pdl.Add(new ParsedData() { IP = m.Groups[1].Value, Port = m.Groups[2].Value, Username = m.Groups[3].Value, Password = m.Groups[4].Value });
Console.WriteLine("IP: " + m.Groups[1] + " PORT: " + m.Groups[2] + " USR_NM: " + m.Groups[3] + " PASS: " + m.Groups[4]);
}
}
}
}
Also I added an List which contains the data.

class Program
{
static void Main(string[] args)
{
//I think you know how to read the file so:
string text =
#"12.23.45.56:8080:username:password
12.23.45.56:8080:username:password
12.23.45.56:8080:username:password
12.23.45.56:8080:username:password";
List<ParsedData> ps = new List<ParsedData>();
text.Split(new char[] { '\r','\n' }, StringSplitOptions.RemoveEmptyEntries).ToList().ForEach(c =>
{
var cols = c.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries).ToList();
//you can check too if cols have content here
ps.Add(new ParsedData()
{
IP = cols[0]!=null?cols[0]:"", //and check if inside it's content..
Port = cols[1],
Username = cols[2],
Password = cols[3]
});
});
foreach(ParsedData p in ps)
{
Console.WriteLine(p.IP + "\t" + p.Port + "\t" + p.Username + "\t" + p.Password);
}
}
}
public class ParsedData
{
public string IP { get; set; }
public string Port { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}

I think you make misunderstood about the pr, it not array now, it the element in the array.
var text = "12.23.45.56:8080:username:password";
var array = text.Split(':');
var data = new ParsedData()
{
IP = array[0],
Port = array[1],
Username = array[2],
Password = array[3]
};

Related

How to create "public string array" from parameter as array?

I have this code:
public static void SendDataToES(String startTimestamp, String startDate, String bid_x, String ask_x)
{
var tem_ehm = new Pre_Market
{
timestamp = startTimestamp,
date = startDate,
bid = bid_x,
ask = ask_x
};
}
class Pre_Market
{
public string x_ric { get; set; }
public string ask { get; set; }
public string bid { get; set; }
public string date { get; set; }
public string timestamp { get; set; }
}
.
But in the future, it will have parameters as Array.
public static void SendDataToES(String startTimestamp, String startDate, String bid_x, String ask_x, IList nameABC, String[] getABCs)
which nameABC[] has value A,B,C and getABC[] has value 1,2,3 so I would like to create in class Pre_Market as Array
public string[] A { get; set;}
public string[] B { get; set;}
public string[] C { get; set;}
Not sure below is working fine ?
for ( int i = 0 ; i < nameABC.Count(); i++ )
{
public string[] nameABC[i] { get; set; }
}
so that the below is available ?
var tem_ehm = new Pre_Market
{
timestamp = startTimestamp,
date = startDate,
bid = bid_x,
ask = ask_x,
A = getABC[0],
B = getABC[1],
C = getABC[2]
};
Updated ! Below is working fine on my side.
var temp_ehm = new Pre_Market
{
timestamp = startTimestamp,
date = startDate,
fids = new Dictionary<string, string>(),
};
for (int i = 0; i < nameFIDs.Count() - 1; i++)
{
temp_ehm.fids.Add(nameFIDs[i], get_FIDs[i]);
}
"fids in temp_ehm can be added" that’s news to me!
If you are ok with using an anonymous class instead of Pre_Market, then You can build up your object structure in JSON ( building a string is easy ), and then use a JSON deserializer (install NewtonSoft.JSON via NuGet) to convert it to an object
Here how you may want to generate your JSON string
string jsonStr = "{ timestamp = \"" + startTimestamp + "\"," +
"date = \"" + startDate + "\"," +
"bid = \"" + bid_x + "\"," +
"ask = \"" + ask_x + "\"";
for ( int i = 0 ; i < nameABC.Count(); i++ )
{
jsonStr += "," + nameABC[i] + " = \"" + getABCs[i] + "\""
}
jsonStr += "}";
A simple solution would be to use a dictionary.
public static void SendDataToES(String startTimestamp, String startDate, String bid_x, String ask_x, IList<string> nameABC, string[] getABCs)
{
var tem_ehm = new Pre_Market
{
timestamp = startTimestamp,
date = startDate,
bid = bid_x,
ask = ask_x,
ABCs = new Dictionary<string, string>()
};
int i = 0;
foreach (string name in nameABCs)
tem_ehm.Add(name, getABCs[i++];
// access the ABCs like so:
string A = tem_ehm.ABCs["A"];
string B = tem_ehm.ABCs["B"];
string C = tem_ehm.ABCs["C"];
}
class Pre_Market
{
public string x_ric { get; set; }
public string ask { get; set; }
public string bid { get; set; }
public string date { get; set; }
public string timestamp { get; set; }
public Dictionary<string, string> ABCs { get; set; }
}

How to compare string inside an array from a text file

I'm writing a code for an ATM project that reads a text file. The text file is written this format:
account number * name * pin * check balance * saving balance
So, I pass it into a method that splits them into an array.
public void linesplitter (string line)
{
string[] split = line.Split('*');
account = int.Parse(info [0]) ;
name = info [1] ;
pin = int.Parse(info [2]) ;
check = info [3] ;
saving = info [4] ;
}
So, when the user enter the account number, it goes to a log in screen where they will enter the name and pin associated with the account number.
My question is how can I compare the name and pin with the account number?
Sample for you.
List<AccountDetails> accountDetails = new List<AccountDetails>();
//Declare class to store your info
public class AccountDetails
{
public String account { get; set; }
public String name { get; set; }
public String pin { get; set; }
public String check { get; set; }
public String saving { get; set; }
}
//This function is a just an example, you need to expand it to fit your solution
public void linesplitter(String line)
{
//You can place your text file reader code here.
//And call this function from Page_Load.
AccountDetails dtl = new AccountDetails();
string[] split = line.Split('*');
dtl.account = int.Parse(info[0]);
dtl.name = info[1];
dtl.pin = int.Parse(info[2]);
dtl.check = info[3];
dtl.saving = info[4];
//Every line from your text file will store to the Global List as declare in 1st line.
accountDetails.Add(dtl);
}
//this is the function that trigger by your Button Event.
//Pass in parameters to this function to get account details.
//So the output for this function, something like
//if(result == null)
// login fail. etc
public AccountDetails GetAccountDetails(String AccountNumber, String Name, String Pin)
{
var result = (from a in accountDetails
where a.account == AccountNumber
&& a.name == Name
&& a.pin == Pin
select a).FirstOrDefault();
return result;
}
As an option, you must gather all information from text file into collection of wrapper class instances, and then after user enteres account number, you find an item in your collection by number, and if such item exists, you expect the desired pin and name, make your validation checks, and etc...
For example you create class:
class AccountInfo
{
public long AccountNumber { get;set; }
public int Pin { get;set; }
public string Name { get;set; }
public string Check { get;set; }
public string Saving { get;set; }
}
And convert yout text data into collection of items:
var textLines = sourceTextData.Split('\r\n').ToList();
var accountsCollection = textLines.Select(i =>
new AccountInfo
{
AccountNumber = Convert.ToDouble(i.Split('*')[0]),
Pin = Int32.Parse(i.Split('*')[1]),
Name = i.Split('*')[2],
Check = i.Split('*')[3],
Saving = i.Split('*')[4]
}).ToList();
Or instead of a list you can prepare a dictionary, where Dictionary keys will be account numbers.
Create a class to store all the account information. As you read the line, create instance of that class and fill up the info and store in the List. Now to compare name and pin you can just use Linq query.
Class AccountInfo
{
public int AccountNumber {get;set;}
public string Name {get;set;}
public int AtmPin {get;set;}
public string Check {get;set;}
public string Saving {get;set;}
}
// Now in your Main program, use that class like this
List<AccountInfo> accountInfoList= new List<AccountInfo>();
foreach(string line in File.ReadAllLines("filename"))
{
AccountInfo ai =new AccountInfo();
string[] split = line.Split('*');
ai.AccountNumber = int.Parse(info [0]) ;
ai.Name = info [1] ;
ai.AtmPin = int.Parse(info [2]) ;
ai.Check = info [3] ;
ai.Saving = info [4] ;
accountInfoList.Add(ai);
}
// Some code to accept name and pin from user
// Now compare name and pine like this
var validationSuccessful = accountInfoList.Any(x=>x.AccountNumber==userEnteredAccountNumber &&
x.Name==userEnteredName &&
x.AtmPin==userEnteredPin);
if(validationSuccessful)
// Display next screen
else
// Display message log in failure
Please keep in mind this is simplest approach. I am assuming you are working on some practice project..Real ATM Project will have lot of security and will do comparison of Pin using Salt and Hash mechanism. It will definitely have some database or service.
As Jannik suggested, this is how you could do comparison without Linq query
bool validationSuccessful=false;
foreach(AccountInfo accountInfo in AccountInfoList)
{
if(accountInfo.AccountNumber==userEnteredAccountNumber &&
accountInfo.Name==userEnteredName &&
accountInfo.AtmPin==userEnteredPin)
{
validationSuccessful = true;
break;
}
}
I prefer you to create a Class for account like the following:
public class Account
{
public int account { get; set; }
public string name { get; set; }
public int pin { get; set; }
public string check { get; set; }
public string saving { get; set; }
}
Then Form a List of accountObjects that includes all the account details from file where the account information ware stored. The iterate the list to check whether there is any matching credentials ware available or not. The code for this complete scenario will be like the following:
List<Account> ATMAccountList = new List<Account>();
foreach (var line in File.ReadAllLines("your Path Here"))
{
ATMAccountList.Add(linesplitter(line));
}
int accountNumberInput = 123, pinInput = 6565;
// This will be the input values from the user
bool matchFound = false;
foreach (var accountItem in ATMAccountList)
{
if (accountItem.account == accountNumberInput && accountItem.pin == pinInput)
{
matchFound = true;
break;
}
}
if (matchFound)
{
//Proceed with account
}
else
{
// display error ! in valid credential
}
Where the method linesplitter will be defined as Like this:
public Account linesplitter(string line)
{
Account AccountObject = new Account();
string[] info = line.Split('*');
AccountObject.account = int.Parse(info[0]);
AccountObject.name = info[1];
AccountObject.pin = int.Parse(info[2]);
AccountObject.check = info[3];
AccountObject.saving = info[4];
return AccountObject;
}
Note :
You can do the same by using LINQ
if (ATMAccountList.Where(x => x.account == accountNumberInput && x.pin == pinInput).Count() == 1)
{
//Proceed with account
}
else
{
// display error ! in valid credentials
}
Here is a basic Console Application that might give you some ideas....
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
//private static XElement AccountData = new XElement("Root");
private static DataSet dataSet = new DataSet();
static void Main(string[] args)
{
DataSet dataSet = new DataSet();
string[] readText = File.ReadAllLines(#"<Path to your account data file>\AccountData.txt");
string strAccountNumber = string.Empty;
string strPin = string.Empty;
string strName = string.Empty;
dataSet.ReadXml(new StringReader(new XElement("Root",
from str in readText
let fields = str.Split('*')
select new XElement("AccountData",
new XAttribute("AccountNo", fields[0]),
new XAttribute("Name", fields[1]),
new XAttribute("Pin", fields[2]),
new XAttribute("ChkBalance", fields[3]),
new XAttribute("SavBalance", fields[4])
)
).ToString()));
do
{
Console.WriteLine("Please enter your Account Number (press 'Q' to exit)");
strAccountNumber = Console.ReadLine().ToLower();
if (dataSet.Tables[0].Select(string.Format("AccountNo = '{0}'", strAccountNumber)).Count() == 1)
{
Console.WriteLine("Please enter your Pin");
strPin = Console.ReadLine().ToLower();
Console.WriteLine("Please enter your Name");
strName = Console.ReadLine();
if (dataSet.Tables[0].Select(string.Format("Pin = '{0}' AND Name = '{1}'", strPin, strName)).Count() == 1)
{
DataRow[] result = dataSet.Tables[0].Select(string.Format("Pin = '{0}' AND Name = '{1}'", strPin, strName));
foreach (DataRow row in result)
{
Console.WriteLine(string.Format("Account Info for :: {0}", strName));
Console.WriteLine("{0}, {1}, {2}, {3}, {4}", row[0], row[1], row[2], row[3], row[4]);
}
}
else
{
Console.WriteLine("Incorrect Details");
}
}
} while (strAccountNumber != "q");
}
}
}
Don't forget the replace the path in.....
string[] readText = File.ReadAllLines ....
with the path to your data.....

Get property names as strings from a input string

I am currently creating a module which will create merge fields in word using Gembox.Document from C#. First of all, I just want to say that this is a task that I have been given, so wether this is a bad way to do it or not, this is the way they want it.
I have a Windows forms application where there is a textbox and a button. In the textbox, they want the possibility to paste a dto/model, for example:
"public class Example
{
public string Name { get; set; }
public string Surname { get; set; }
public string Cellphone { get; set; }
public string Address { get; set; }
public string CompanyName { get; set; }
public DateTime CurrentDate { get; set; }
}"
I already have the logic to add mergefields to word with a method where I pass in a string[] which contains all the merge field names.
PROBLEM IS: I need to be able to somehow substring this big string above which contains a dto/model written as a string in the textbox, to get the property names and add them to the string[], since they will be the merge field names.
I hope I could explain myself well enough. This is my first question here and I am not used to explain my problems in English.
EDIT:
To specify the problem: I need to get the property names out of this string and put them into an string[]:
string s = #"public string Name { get; set; }
public string Surname { get; set; }
public string Cellphone { get; set; }
public string Address { get; set; }
public string CompanyName { get; set; }
public DateTime CurrentDate { get; set; }"
I think that maybe you should parse this text (using parser not own solution) and than search syntax tree to find properties names. I think about something similar to this:
Using NRefactory for analyzing C# code
This code returns complete tree or error (I use NRefactory but you can use Roslyn):
var parser = new CSharpParser();
var syntaxTree = parser.Parse(programCode);
than search syntaxTree field for properties.
Example code:
const string code = #"public class Example {
public string Name { get; set; }
public string Surname { get; set; }
public string Cellphone { get; set; }
public string Address { get; set; }
public string CompanyName { get; set; }
public DateTime CurrentDate { get; set; }
}";
var syntaxTree = new CSharpParser().Parse(code, "program.cs");
var listOfPropertiesNames = syntaxTree.Children
.SelectMany(astParentNode => astParentNode.Children)
.OfType<PropertyDeclaration>()
.Select(astPropertyNode => astPropertyNode.Name)
.ToList();
This snippet extract properties names.
You can use the CSharpCodeProvider class to compile your code to an assembly, and then use reflection to find the types in the compiled assembly.
var sourcePart = #"public class Example
{
public string Name { get; set; }
public string Surname { get; set; }
public string Cellphone { get; set; }
public string Address { get; set; }
public string CompanyName { get; set; }
public DateTime CurrentDate { get; set; }
}";
var sourceTemplate = #"using System;
#code
";
var code = sourceTemplate.Replace("#code", sourcePart);
CSharpCodeProvider c = new CSharpCodeProvider();
CompilerParameters cp = new CompilerParameters();
CompilerResults cr = c.CompileAssemblyFromSource(cp, code);
if (cr.Errors.Count > 0)
{
MessageBox.Show("ERROR: " + cr.Errors[0].ErrorText,
"Error evaluating cs code", MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
var a = cr.CompiledAssembly;
var type = a.GetTypes().Single();
string[] propertyNames = type.GetProperties().Select(p => p.Name).ToArray();
UPDATE:
Remeber however, that a type loaded in an app domain can't be unloaded, and will keep consuming memory until the application exit.
So if the user works with this function a lot, memory would be consumed incrementally.
If this becomes a problem, you can workaround this by creating a separate app domain or spawn another process to serve this function, but it's another question.
You can create custom static method to parse your text. What it does it jumps across string from one index of '{' to next index goes backward and checks if there is '(' or ')' char (which indicates that it is a method and not a property and it should skip it) and goes backwards to find the beginning of the property. After that it extracts value, then jumps to next index of '{' char and so on :
static string[] GetProperties(string dirty)
{
List<string> properties = new List<string>();
int i = dirty.IndexOf("{ ");
StringBuilder sb = new StringBuilder();
int propEndIndex = -1; int i2 = -1;
for (; i != -1; i = dirty.IndexOf("{ ", i + 1))
{
i2 = i - 1;
for (; dirty[i2] == ' '; i2--) { }
if (dirty[i2] == '(' || dirty[i2] == ')') continue;
propEndIndex = i2 + 1;
for (; dirty[i2] != ' '; i2--) { }
for (i2++; i2 < propEndIndex; i2++)
sb.Append(dirty[i2]);
properties.Add(sb.ToString());
sb.Clear();
}
return properties.ToArray();
}
Example of usage :
Stopwatch sw = new Stopwatch();
var s = #"public class Example
{
public string Name { get; set; }
public string Surname { get; set; }
public string Cellphone { get; set; }
public string Address { get; set; }
public string CompanyName { get; set; }
public DateTime CurrentDate { get; set; }
public void MyMethod() { }
}";
sw.Start();
string[] props = GetProperties(s);
sw.Stop();
foreach (var item in props)
Console.WriteLine(item);
Console.WriteLine("\n\nMethod is executed in " + sw.ElapsedMilliseconds + " ms");
Console.ReadKey();
Output:
Name
Surname
CellPhone
Address
CompanyName
CurrentDate
Method is executed in 1 ms

Results from C# JSON-Deserialization to String

I used json2csharp to generate functions and classes but I am a bloody newbie. What I want is using the Data from the JSON Array and display it in a Textbox.
Here is the Code:
public class Sent_SMS
{
public string status { get; set; }
public string error { get; set; }
public string smslog_id { get; set; }
public string queue { get; set; }
public string to { get; set; }
}
public class RootObject
{
public List<Sent_SMS> data { get; set; }
public object error_string { get; set; }
public int timestamp { get; set; }
}
public void doSendSMS()
{
/* API URLs */
APIURL_Send = "http://ipadressofgateway/playsms/index.php?app=ws&op=pv&h=" + apikey + "&u=" + username + "&to=" + receiver_number + "&msg=" + message; // Sending Message
using (WebClient wc = new WebClient())
{
var json = wc.DownloadString(APIURL_Send);
var SMS_Log = JsonConvert.DeserializeObject<RootObject>(json);
richTextBox3.Text = "SMS has been sent to:" + SMS_Log.data.to + "Status is:" + SMS_Log.data.status;
}
}
But of course.. this does not work cause "SMS_Log.data.to" and "SMS_Log.data.status" is not correct. How to do this right?
Regards
If you're sure there is always exactly one SMS in the response, then change your code to:
richTextBox3.Text = "SMS has been sent to:" + SMS_Log.data[0].to + "Status is:" + SMS_Log.data[0].status;
Otherwise, I'd go for a solution like this:
var text = "";
foreach (var sms in SMS_Log.data) {
text += "SMS has been sent to:" + sms.to + "Status is:" + sms.status + "\n";
}
richTextBox3.Text = text;
SMS_Log.data is a list of Sent_SMS instances, so you'd have to iterate through that list to get each individual message's data.
for(int i=0;i<SMS_Log.data.Count();i++)
{
richTextBox3.Text = "SMS has been sent to:" + SMS_Log.data[i].to + "Status is:" + SMS_Log.data[i].status;
}
Though this would set only the last element as your TextBlock text. Would recommend you to add these into a new List and set this list as a source of GridView or ListView

Variable declaration in the loop using Json

Here is my code in the controller.
public JsonResult directory()
{
List<string> alp = new List<string>();
var alp1 = new List<directories>();
string array = "";
int a = 0;
for (a = 0; a <= 25; a++)
{
int unicode = a + 65;
char character = (char)unicode;
string text1 = character.ToString();
string url1 = "<a href='/Directories/?search=" + text1 + "' 'rel=" + text1 + "'>";
string alpha = text1;
alp.Add(url1);
alphatxt.Add(alpha);
}
var alphaa = alp1.Add(new directories { arrary = url1, character = alphatxt });
return Json(alphaa, JsonRequestBehavior.AllowGet);
}
public class directories
{
public int a { get; set; }
public int unicode { get; set; }
public char character { get; set; }
public string[] arrary { get; set; }
}
Outputs are getting by
alp.Add(url1);
alp.Add(alpha);
How can i call these two outputs outside the loop.
so that i will get my output through the return
Json(alphaa, JsonRequestBehavior.AllowGet);
But I dont know how to declare the output to the variable outside the loop.
If you are trying to build a list of urls, one for each letter, then you can simply do something like:
public List<Directory> GetDirectories()
{
var dirs = new List<Directory>();
for (var ch = 'A'; ch <= 'Z'; ch++)
{
var url = string.Format(
"<a href='/Directories/?search={0}' rel='{0}'>", ch);
dirs.Add(new Directory() { Character = ch, Url = url });
}
return dirs;
}
// Directory class is simplifed a bit in this example
public class Directory
{
public char Character { get; set; }
public string Url { get; set; }
}
And then simply convert it to JSON in a separate method:
public JsonResult directory()
{
var dirs = GetDirectories();
return Json(dirs, JsonRequestBehavior.AllowGet);
}
Using LINQ, it could be simplified to:
private static readonly string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public List<Directory> GetDirectories()
{
return Alphabet
.Select(ch => new Directory() { Character = ch, Url = CreateUrl(ch) })
.ToList();
}
private string CreateUrl(char ch)
{
return string.Format("<a href='/Directories/?search={0}' 'rel={0}'>", ch);
}
The way your code looks right now, it doesn't seem like you need to create this list on the server side at all (you are transferring a bunch of almost equal hard-coded URLs, which can easily be created on the client side using JavaScript), so I presume there is some additional data you are transferring with this query?
You can access the JsonResult.Data property, but I don't really think that is what you need. I suggest to create a method that return the actual result, and inside your action you call that one and serialize it as JSON:
public JsonResult directory()
{
return Json(this.GetDirectories(), JsonRequestBehavior.AllowGet);
}
private List<directories> GetDirectories()
{
... // your original code
}
I tried in many ways, At last got idea to use this way,
Also My code is shown below.
public JsonResult directory()
{
List<string> alp = new List<string>();
var alp1 = new List<directories>();
string array = "";
int a = 0;
for (a = 0; a <= 25; a++)
{
int unicode = a + 65;
char character = (char)unicode;
string text1 = character.ToString();
string url1 = "<a href='/Directories/?search=" + text1 + "' 'rel=" + text1 + "'>";
string alpha = text1;
alp.Add(url1);
alp.Add(alpha);
alp1.Add(new directories { dirurl = url1, text = alpha });
}
return Json(alp1, JsonRequestBehavior.AllowGet);
}
public class directories
{
public string text { get; set; }
public string dirurl { get; set; }
}
}
}

Categories