Foreach string occurrence - c#

So I would like to read out all occurrences in C# in one string and work with it. Means I need the position of the part string, but I don't know how. Example:
The main string can look like this:
Currently there are %count{"only_groups":"1, 2, 3","ignore_channels":"1, 2, 3"}% supporters online, %count{"ignore_channels":"1, 2, 3","querys":"false"}% of them are afk. These are the active supporters: %list{"querys":"false","only_groups":"1, 2, 3"}%
Contentwise this string makes no sense, but I think you can understand what I mean by these strings. There are also more possible variables besides %count% and %list%
Now I want to keep all these variables and replace something instead.
I already have the following code, but it would only replace one variable and it would only recognize the %count% variable if it is completely lower case:
int pFrom = channel_name.IndexOf("%count{") + "%count{".Length;
int pTo = channel_name.LastIndexOf("}%");
string result = channel_name.Substring(pFrom, pTo - pFrom);
Logger.Info(result);
string json2 = #"{" + result + "}";
JObject o2 = JObject.Parse(json2);
foreach (JProperty property in o2.Properties())
{
var pname = property.Name;
if (pname == "only_groups")
{
only_groups = property.Value.ToString();
}
else if (pname == "ignore_groups")
{
ignore_groups = property.Value.ToString();
}
else if (pname == "only_channels")
{
only_channels = property.Value.ToString();
}
else if (pname == "ignore_channels")
{
ignore_channels = property.Value.ToString();
}
else if (pname == "away")
{
away = property.Value.ToString();
}
else if (pname == "querys")
{
query = property.Value.ToString();
}
}
var serverVar = (await fullClient.GetServerVariables()).Value;
if (query.Equals("only"))
{
channel_name = "User online: " + serverVar.QueriesOnline;
}
else if (query.Equals("ignore"))
{
channel_name = "User online: " + (serverVar.ClientsOnline - serverVar.QueriesOnline);
}
else
{
channel_name = "User online: " + serverVar.ClientsOnline;
}
I hope people understand what I'm about to do. My English is not the best

Use Regex.Matches() to get a list of all occurences.
This pattern will find all variables including configuration json:
(?s)%.*?%
Then you just need to extract the 2 parts out of the matched value.
This will find only the variable name within the matched value:
(?s)(?<=%).+?(?=({|%))
This will find the JSON configuration within the matched value if there is any:
(?s){.*}
Only caveat is you can't use % character anywhere in text outside of variables.

Related

How to Get index of a Character in an Unknown Line of a Multiline string in c#

I'm trying to get covid-19 results (only information about Iran) from an Api and show it on a textbox.
and the full result (all countries) that i get from the Api is a json format.
so to get only Iran section i made a Function that loops through lines of the string one by one and check if in that line there is a "{" and if yes get index of that and continue checking if in another line there is a "}" and get index of that too then check if between these, there is "Iran" then add this text (from "{" to "}") in a string:
private string getBetween(string strSourceText, string strStartingPosition, string strEndingPosition)
{
int Starting_CurlyBracket_Index = 0;
int Ending_CurlyBracket_Index = 0;
string FinalText = null;
bool isTurnTo_firstIf = true;
foreach (var line in strSourceText.Split('\r', '\n'))
{
if (isTurnTo_firstIf == true)
{
if (line.Contains(strStartingPosition))
{
Starting_CurlyBracket_Index = line.IndexOf(strStartingPosition); //i think problem is here
isTurnTo_firstIf = false;
}
}
else if (isTurnTo_firstIf == false)
{
if (line.Contains(strEndingPosition))
{
Ending_CurlyBracket_Index = line.IndexOf(strEndingPosition); //i think problem is here
if (strSourceText.Substring(Starting_CurlyBracket_Index, Ending_CurlyBracket_Index - Starting_CurlyBracket_Index).Contains("Iran")) //error here
{
FinalText = strSourceText.Substring(Starting_CurlyBracket_Index, Ending_CurlyBracket_Index - Starting_CurlyBracket_Index);
break;
}
else
{
isTurnTo_firstIf = true;
}
}
}
}
return FinalText;
}
and i call the function like this:
string OnlyIranSection = getBetween(Sorted_Covid19_Result, "{", "}"); //Sorted_Covid19_Result is the full result in json format that converted to string
textBox1.Text = OnlyIranSection;
but i get this Error:
and i know.. its because it gets indexes in the current line but what i need is getting that index in the strSourceText so i can show only this section of the whole result:
USING JSON
As per the comments I read it was really needed to use JSON utility to achieve your needs easier.
You can start with this basic example:
static void Main(string[] args)
{
string jsonString = #"{
""results"": [
{""continent"":""Asia"",""country"":""Indonesia""},
{""continent"":""Asia"",""country"":""Iran""},
{""continent"":""Asia"",""country"":""Philippines""}
]
}";
var result = JsonConvert.DeserializeObject<JsonResult>(jsonString);
var iranInfo = result.InfoList.Where(i => i.Country.ToString() == "Iran").FirstOrDefault();
}
public class JsonResult
{
[JsonProperty("results")]
public List<Info> InfoList { get; set; }
}
public class Info
{
public object Continent { get; set; }
public object Country { get; set; }
}
UPDATE: USING INDEX
As long as the structure of the JSON is consistent always then this kind of sample solution can give you hint.
Console.WriteLine("Original JSON:");
Console.WriteLine(jsonString);
Console.WriteLine();
Console.WriteLine("Step1: Make the json as single line,");
jsonString = jsonString.Replace(" ", "").Replace(Environment.NewLine, " ");
Console.WriteLine(jsonString);
Console.WriteLine();
Console.WriteLine("Step2: Get index of country Iran. And use that index to get the below output using substring.");
var iranIndex = jsonString.ToLower().IndexOf(#"""country"":""iran""");
var iranInitialInfo = jsonString.Substring(iranIndex);
Console.WriteLine(iranInitialInfo);
Console.WriteLine();
Console.WriteLine("Step3: Get inedx of continent. And use that index to get below output using substring.");
var continentIndex = iranInitialInfo.IndexOf(#"""continent"":");
iranInitialInfo = iranInitialInfo.Substring(0, continentIndex-3);
Console.WriteLine(iranInitialInfo);
Console.WriteLine();
Console.WriteLine("Step4: Get the first part of the info by using. And combine it with the initialInfo to bring the output below.");
var beginningIranInfo = jsonString.Substring(0, iranIndex);
var lastOpenCurlyBraceIndex = beginningIranInfo.LastIndexOf("{");
beginningIranInfo = beginningIranInfo.Substring(lastOpenCurlyBraceIndex);
var iranInfo = beginningIranInfo + iranInitialInfo;
Console.WriteLine(iranInfo);
OUTPUT USING INDEX:

How to use list values globally in asp.net c#

I want to use the below list globally in my aspx page whose name is lstUMSGroupDetails. Currently I am getting its value from a function.
I want to use that list values in other functions too. SO how should I make it global.
its code is below
private void Get_AuthenticateUser_Ums(string strUName)
{
string strCurrentGroupName = "";
int intCurrentGroupID = 0;
try
{
if (!string.IsNullOrEmpty(strUName))
{
List<IPColoBilling.App_Code.UMS.UMSGroupDetails> lstUMSGroupDetails = null;
List<IPColoBilling.App_Code.UMS.UMSLocationDetails> lstUMSLocationDetails = null;
objGetUMS.GetUMSGroups(strUserName, out strCurrentGroupName, out intCurrentGroupID, out lstUMSLocationDetails, out lstUMSGroupDetails);
if (strCurrentGroupName != "" && intCurrentGroupID != 0)
{
strCurrentGrp = strCurrentGroupName;
intCurrentGrpId = intCurrentGroupID;
}
else
{
Response.Redirect("~/NotAuthorize.aspx", false);
}
}
}
catch (Exception ex)
{
string strErrorMsg = ex.Message.ToString() + " " + "StackTrace :" + ex.StackTrace.ToString();
CommonDB.WriteLog("ERROR:" + strErrorMsg, ConfigurationManager.AppSettings["IPCOLO_LOG"].ToString());
}
You can store it in Session.
Session["lstUMSGroupDetails"] = lstUMSGroupDetails;
Then you can get this by.
List<IPColoBilling.App_Code.UMS.UMSGroupDetails> lstUMSGroupDetails = (List<IPColoBilling.App_Code.UMS.UMSGroupDetails>)Session["lstUMSGroupDetails"];
For more information please see MSDN Reference.
Could you not assign it to a slot in the Session Dictionary?
For example:
var myList = new List<int>();
Session["groups"] = myList;

How to display the first special character entered in textbox, in a label

I have created a regex function and called it when the data is being saved.
public static bool CheckSpecialCharacter(string value)
{
System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(#"[~`!##$%^*()=|\{}';.,<>]");
if (regex.IsMatch(value))
{
return false;
}
else
{
return true;
}
}
Used here:
if (ClassName.CheckSpecialCharacter(txt_ExpName1.Text)==false)
{
lblErrMsg.Text = "Special characters not allowed";
return;
}
Now instead of writing "Special characters not allowed", I want to attach the 1st special character that was entered in the textbox, so
if # was entered, the message should be read as "Special character # not allowed"
Is it possible to do this? please help.Thanks.
Try following code.
public static string CheckSpecialCharacter(string value)
{
System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(#"[~`!##$%^*()=|\{}';.,<>]");
var match = regex.Match(value);
if (match.Success)
{
return match.Value;
}
else
{
return string.empty;
}
}
usage:
var value = ClassName.CheckSpecialCharacter(txt_ExpName1.Text);
if (!string.IsNullOrEmpty(value ))
{
lblErrMsg.Text = value + " Special characters not allowed";
return;
}
OR you can do it by returning bool and adding one out parameter in the function, but i will not suggest that.. check this link
EDIT - To do the same thing in Javascript
function CheckSpecialCharacter(value)
{
var res = value.match(/[~`!##$%^*()=|\{}';.,<>]/g);
return res == null ? "" : res[0];
}
usage:
var value = CheckSpecialCharacter(document.getElementById("txt_ExpName1").value);
if(value != "")
{
document.getElementById("lblErrMsg").innerHTML = value + " Special characters not allowed";
}
Try this:
public static bool CheckSpecialCharacter(string value, out string character)
{
var regex = new System.Text.RegularExpressions.Regex(#"[~`!##$%^*()=|\{}';.,<>]");
var match = regex.Match(value);
character = regex.Match(value).Value;
return match.Length == 0;
}
and then
string character;
if (ClassName.CheckSpecialCharacter(txt_ExpName1.Text, out character) == false)
{
lblErrMsg.Text = character + " Special characters not allowed";
return;
}
You can just use the Matches(string) function from Regex to get the matches then check the first element like this :
var regex = new Regex(#"[~`!##$%^*()=|\{}';.,<>]");
var matches = regex.Matches("This contains # two b#d characters");
if (matches.Count > 0)
{
var firstBadCharacter = matches[0];
}
Then you can wrap the result of your check in an Exception :
throw new ArgumentException("Special character '" + firstBadCharacter + "' not allowed.");

C# Webservice stucks. Need to override published file to restart

Please help me, I'm facing a fatal problem here. If someone could fix this, I swear I will treat u to a huge drink whenever u step into my country (Vietnam). Ok here's the problem: I'm coding a webservice for multi connection simultaneously from tablet (around 100 clients). It ran well but recently whenever high traffic occurs, my webservice seems to stuck somehow and I need to copy - override the published file of webservice in order for it to run again (restart website in IIS is no use) ...
This is my w/s code for handling the data:
public string Info_Handling(string id, string name, string strDetails)
{
string checkExist = "";
string str = "";
string str2 = "";
MLL_Customer _customerClient = new MLL_Customer();
MLL_CustomerCategory _categoryClient = new MLL_CustomerCategory();
MLL_Product _productClient = new MLL_Product();
MLL_SampleProduct _sampleClient = new MLL_SampleProduct();
if (_customerClient.CheckExistCustomer(id, name.ToUpper(), 2) == 1) // SID & NAME
{
checkExist = "EXIST";
}
using (SqlConnection connection = new SqlConnection(ConfigurationSettings.AppSettings["Main.ConnectionString"]))
{
connection.Open();
SqlTransaction trans = connection.BeginTransaction("XXX");
try
{
// ID Example: 11 means VIP - 12 means Normal - 13 means ples... jkg
// First - Insert Customer
string strCustomerCategory = _categoryClient.SelectCategoryByID(id).ToString();
if (!checkExist.Equals("EXIST"))
{
Customer businessObject = new Customer();
businessObject.ID = sid;
businessObject.Name = name.ToUpper();
businessObject.CategoryID = strCustomerCategory;
str = "" + _customerClient.Insert(businessObject, connection, trans);
}
// Second Insert Product spliting from a string Ex: "TV&Laptop&CD"
string[] productDetails = strDetails.Split(new char[] { '&' });
object obj3;
SampleProduct objSample;
Product objProduct;
for (int j = 0; j < productDetails.Length; j++)
{
if (_productClient.CheckExist(id, productDetails[j])) == null) // Check if customer already owns this product
{
// Get the properties of sample product.
objSample = _sampleClient.SelectSampleProduct(productDetails[j]);
objProduct = new Product();
objProduct.SID = sid;
objProduct.Testcode = objSample.TestCode;
objProduct.Category = objSample.Category;
objProduct.Unit = objSample.Unit;
objProduct.Price = objSample.Price;
if (_productClient.Insert(objProduct, connection, trans) != 0)
{
str2 = str2 + "&" + objProduct.Testcode;
// return the code of product in order to see which product has been inserted successfully
}
}
}
trans.Commit();
SqlConnection.ClearAllPools();
}
catch (Exception exception)
{
str = "0";
str2 = exception.Message + exception.Source;
try
{
trans.Rollback();
}
catch (Exception)
{
}
}
}
if (!str2.Equals(""))
{
return (str + "&" + id + str2);
}
return ("0&" + sid + str);
}
I modified the code but this is basically how i roll. Could anyone plz tell me some solution. Deeply thank u.
1 more thing about ClearAllPools() method: I know how it works but I dont even know why I need it. Without this, my data will be messed up terrible. CategoryID of one customer will be assigned for another customer sometimes. ???? How could it happened ?? HELP

Index was outside the bounds of the array C# in unit test

I input my QuaterDisplay as dummy data, but I get the error as below:
Index was outside the bounds of the array.
Code:
private string GetQuarterDisplay(DateTime dateKey)
{
return ((AvailabilityDS.IntelTimeRow[])mAvailabilityDS.Time.Select("DateKey = '"
+ dateKey + "'"))[0].QuarterDisplay; //error occur here
}
internal void PropagateModelStartQuarter()
{
object[] args = new object[0];
m_privateObject.Invoke("PropagateModelStartQuarter", new System.Type[0], args);
}
I am pretty sure this is the line in error:
((AvailabilityDS.IntelTimeRow[])mAvailabilityDS.Time.Select("DateKey = '"
+ dateKey + "'"))[0]
I guess there is no item on that time stamp, resulting in an empty array. If you try to access the first item in an empty array, that is the error you get.
If you use LINQ, you could use FirstOrDefault, which will not fail when there is no item. Instead, it will return the default value. In this case null:
var availability = ((AvailabilityDS.IntelTimeRow[])mAvailabilityDS.Time.Select("DateKey = '"
+ dateKey + "'")).FirstOrDefault();
and then:
if (availability != null)
{
return availability.QuarterDisplay;
}
else
{
// return a default value, or throw an exception
return null;
}
This means that there is no row in mAvailabilityDS table Time with specified DateKey string representation.
I would replace this with strongly typed LINQ solution:
private string GetQuarterDisplay(DateTime dateKey)
{
return ((AvailabilityDS.IntelTimeRow[])mAvailabilityDS.Time.Select()
.Where(x => x.DateKey == dateKey)
.Select(x => x.QuarterDisplay)
.FirstOrDefault();
}
EDIT
The main problem is that you are searching your rows by string representation of date/time object which is dependant on the current culture used.
This string representation does not match standard ISO format datetime (like 2009-11-03 00:00:00) that is used in DataTable internals to filter values.
If you really want to use not-strongly-typed approach, convert datet/time object to string using invariant culture.
private string GetQuarterDisplay(DateTime dateKey)
{
return ((AvailabilityDS.IntelTimeRow[])mAvailabilityDS.Time.Select("DateKey = '"
+ dateKey.ToString(DateTimeFormatInfo.InvariantInfo) + "'"))[0].QuarterDisplay;
}
why don't you check for null?
private string GetQuarterDisplay(DateTime dateKey)
{
var availabilityDS = (AvailabilityDS.IntelTimeRow[])mAvailabilityDS
if(availabilityDS != null)
{
var time = availabilityDS.Time;
if(time != null)
{
var elements = availabilityDS.Select('"+ dateKey + "'");
if(elements.Any())
{
return elements[0].QuarterDisplay;
}
}
}
return null;
}
You are assuming that the Select class returns an item. If it's an empty array then you are indexing into an empty array. Use something like:
private string GetQuarterDisplay(DateTime dateKey)
{
var times =((AvailabilityDS.IntelTimeRow[])mAvailabilityDS.Time.Select("DateKey = '"
+ dateKey + "'"));
if (times.Length > 0)
{
return times[0].QuarterDisplay;
}
return null; // Or whatever
}
Alternatively use if (!times.Any())...
DataTable.Select didn't return any rows, therefore you get the mentioned exception if you try to access a non-existing row.
You may want to use LINQ instead which makes it much more readable:
var timeRow = mAvailabilityDS.Time.FirstOrDefault(x => x.DateKey == dateKey);
if(timeRow != null)
return timeRow.QuarterDisplay;
else
return null;
Maybe you don't find any rows because there is a time portion that you want to ignore. Then you can use the Date property of DateTime:
var timeRow = mAvailabilityDS.Time.FirstOrDefault(x => x.DateKey.Date == dateKey.Date);

Categories

Resources