I have this piece of code
Category featured = new Category()
{
active = true,
Categories = new Category[0],
description = "",
identifier = "featured",
name = "Featured",
Products = new Product[0],
url = siteUrl,
};
StatisticCounters.CategoriesCounter();
then below this I have this code.
private IList<Category> FeatureSubCategories(HtmlNode std, Category category,Category featured)
{
List<Category> categories = new List<Category>();
{
if (category.name == "Featured")
{
var nodes = std.SelectNodes("//span[contains(#class,'widget')] [position() <= 4]"); //TODO
foreach (var node in nodes)
{
string name = SiteParserUtilities.ParserUtilities.CleanText(System.Net.WebUtility.HtmlDecode(node.InnerText));
string url = node.Attributes["href"].Value;
string identifier = url.Split('/').Last().Replace(".html", "");
WriteQueue.write(string.Format(" Category [{0}].. {1} ", name, url));
IList<Category> sub = GetSubCategories(std);
Category c = new Category()
{
active = true,
Categories = sub.ToArray(),
description = "",
identifier = identifier,
name = name,
Products = new Product[0],
url = url,
};
StatisticCounters.CategoriesCounter();
categories.Add(c);
}
}
}
return categories;
}
for some reason tho when I run the code the if statement if (category.name == "Featured") is never called and I am not sure why this is. To start to parse the xpath and store them links into an array. Thank you for any help which you can give.
It is best to check in debugger. Some times whites spaces cause the problem. It is simple mistake done by many programmers. When we get data from database, there may be some leading spaces. When we compare with some value (thinking that there is no leading space), it will not compare without trimming those spaces. For example
string s1 = "TEST";
string s2 = " TEST";
if (s1 == s2) {
Console.WriteLine("Equal");
}
Please use trim function to remove any white spaces and compare.
Related
I'm learning C# since the past week and databases since a couple of days ago, so if you see something dodgy and you ask yourself "Why did he do that like that?", the answer is probably going to be "Because that's all I know for the moment".
In the title I said "of letters" because if I use a string of numbers, it works.
I have a tiny database with three columns. Id (int), FirstName (text) and LastName (text).
Id is unique, primary key and autoincrements. FirstName is unique. The three are not null.
In that database I have two records:
Id FirstName LastName
3- 6666 2222
4- Test O'Test
This is my method:
public static bool isOnDb(string nombre, string apellido)
{
bool flag = false;
{
try
{
using (IDbConnection cnn = new SQLiteConnection(LoadConnectionString()))
{
string tempName = "Test"; // This is temporarily replacing the argument 'nombre'
int tempNum= 3; // More testing. See below
//cnn.Query<Person>($"select * from Person where FirstName = { tempName }", new DynamicParameters());
// This four lines below are just for testing. They are going to be deleted
var output = cnn.Query<Person>($"select * from Person where FirstName = { tempName }", new DynamicParameters());
var person = output.First();
Console.WriteLine("Funciona");
Console.WriteLine($"{ person.Id } - { person.FullName }");
flag = true;
return flag;
}
}
catch (Exception)
{
Console.WriteLine("Derecho a excepcion");
return flag;
}
}
}
Basically, if tempName = "Test", it falls into an exception. But if tempName = "6666" it returns the row.
I also tried selecting by id. That's why tempNum is there.
int tempNum= 4;
var output = cnn.Query<Person>($"select * from Person where Id = { tempNum }", new DynamicParameters());
Well in SQLite the strings are signified by '' so when you pass FirstName = { tempName } and its FirstName = Test it looks for the column called Test in Table person rather than equating it to the 'Test' string
So you can do:
var output = cnn.Query<Person>($"select * from Person where FirstName = '{ tempName }'");
Or better yet:
var people = cnn.Query<Person>("SELECT * FROM PERSON WHERE FirstName = #FirstName", new { FirstName = tempName });
I have a list with this structure:
public class Amendment{
public string name
public string groupnumber
public string edition
public string destination
}
The data is as follows
var amendmentOne = new Amendment{
name = "Apple",
groupnumber = "A12345",
edition = "A55600E01"
phonenumber = "2232132123"
}
var amendmentTwo = new Amendment{
name = "Apple",
groupnumber = "AG2222",
edition = "A55600E02"
phonenumber = "2232132123"
}
var amendmentThree = new Amendment{
name = "Apple",
groupnumber = "AG55555",
edition = "A55600E03"
phonenumber = "2232132123"
}
Is it possible to somehow get the list item with edition number A55600E03 from the list when I loop through it? The edition numbers are all the same except for the last few characters as they will always be E[number]
Should be as easy as
var result = List.Orderby(x => edition).Last();
Example
var list = new List<Amendment>{amendmentThree, amendmentOne, amendmentTwo};
var result = list.OrderBy(x => x.edition).Last();
Console.WriteLine(result.edition);
Output
A55600E03
Full Demo Here
I have a search bar that executes a lucene query on the "description" field, but it doesn't return results when with apostrophes. For example, I have a product where the description is Herter's® EZ-Load 200lb Feeder - 99018. When I search for "Herter", I get results, but I get no results if I search for "Herter's" or "Herters". This is my search code:
var query = Request.QueryString["q"];
var search = HttpContext.Current.Server.UrlDecode(query);
var rewardProductLookup = new RewardCatalogDataHelper();
RewardProductSearchCriteria criteria = new RewardProductSearchCriteria()
{
keywords = search,
pageSize = 1000,
sortDirection = "desc"
};
IEnumerable<SkinnyItem> foundProducts = rewardProductLookup.FindByKeywordQuery(criteria);
public IEnumerable<SkinnyItem> FindByKeywordQuery(RewardProductSearchCriteria query)
{
var luceneIndexDataContext = new LuceneDataContext("rewardproducts", _dbName);
string fieldToQuery = "rpdescription";
bool sortDirection = query.sortDirection.ToLower().Equals("desc");
MultiPhraseQuery multiPhraseQuery = new MultiPhraseQuery();
var keywords = query.keywords.ToLower().Split(',');
foreach (var keyword in keywords)
{
if (!String.IsNullOrEmpty(keyword))
{
var term = new Term(fieldToQuery, keyword);
multiPhraseQuery.Add(term);
}
}
var booleanQuery = new BooleanQuery();
booleanQuery.Add(multiPhraseQuery, BooleanClause.Occur.MUST);
return
luceneIndexDataContext.BooleanQuerySearch(booleanQuery, fieldToQuery, sortDirection)
.Where(i => i.Fields["eligibleforpurchase"] == "1");
}
The problem here is analysis. You haven't specified the analyzer being used in this case, so I'll assume it's StandardAnalyzer.
When analyzed, the term "Herter's" will be translated to "herter". However, no analyzer is being applied in your FindByKeywordQuery method, so looking for "herter" works, but "herter's" doesn't.
One solution would be to use the QueryParser, in stead of manually constructing a MultiPhraseQuery. The QueryParser will handle tokenizing, lowercasing, and such. Something like:
QueryParser parser = new QueryParser(VERSION, "text", new StandardAnalyzer(VERSION));
Query query = parser.Parse("\"" + query.keywords + "\"");
The single quote is the delimiter for text fields in a query.
Select * FROM Product where Description = 'foo'
You will need to escape or double any single quote your query. try this in the loop.
foreach (var keyword in keywords)
{
if (!String.IsNullOrEmpty(keyword))
{
var term = new Term(fieldToQuery, keyword);
term = term.Replace("'", "''");
multiPhraseQuery.Add(term);
}
}
You could also create an extension method
[DebuggerStepThrough]
public static string SanitizeSQL(this string value)
{
return value.Replace("'", "''").Replace("\\", "\\\\");
}
in which case you could then you could do this in the loop
foreach (var keyword in keywords)
{
if (!String.IsNullOrEmpty(keyword))
{
var term = new Term(fieldToQuery, keyword.SanitizeSQL());
multiPhraseQuery.Add(term);
}
}
Hope this helps.
In my application I would like add Brand and MPN to existing eBay item via API on C#, so, I run code:
string eCommerceID = (dr["eCommerceID"] ?? "").ToString().Trim();
string upc = (dr["UPC"] ?? "").ToString().Trim();
string manufacturerName = (dr["ManufacturerName"] ?? "").ToString().Trim();
string brandMPN = (dr["BrandMPN"] ?? "").ToString().Trim();
ReviseItemRequestType reviseItemRequestType = new ReviseItemRequestType();
reviseItemRequestType.Version = version;
reviseItemRequestType.Item = new ItemType();
reviseItemRequestType.Item.ItemID = eCommerceID;
reviseItemRequestType.Item.ProductListingDetails = new ProductListingDetailsType();
reviseItemRequestType.Item.ProductListingDetails.UPC = upc;
reviseItemRequestType.Item.ProductListingDetails.BrandMPN = new BrandMPNType();
reviseItemRequestType.Item.ProductListingDetails.BrandMPN.Brand = manufacturerName;
reviseItemRequestType.Item.ProductListingDetails.BrandMPN.MPN = brandMPN;
ReviseItemResponseType reviseItemResponseType = ebayService.ReviseItem(reviseItemRequestType);
but when I execute this code, eBay returns error:
"The item specific Brand is missing. Add Brand to this listing, enter a valid value, and then try again."
What I'm doing wrong?
Appreciate any help. Thanks.
Error:
As the error messages says:
The item specific Brand is missing
Don't use the Item.ProductListingDetails.BrandMPN in your request. Instead you will need to create two Item Specifics called Band and MPN.
<ItemSpecifics>
<NameValueList>
<Name>Brand</Name>
<Value>[BRAND VALUE]</Value>
</NameValueList>
<NameValueList>
<Name>MPN</Name>
<Value>[MPN VALUE]</Value>
</NameValueList>
</ItemSpecifics>
Here is copy paste code snippet of the C# solution.
ItemType itemType = new ItemType(); // = class eBay.Service.Core.Soap.ItemType
Int32 condCodeAsInt = 1000; // upto you to derrive this from your use case.
String myBrandValue = "Some BRAND";
String myMpnValue = "some MPN";
String myUpcValue = "Does not apply";
....
//if condition is "New" or "New with Details" then we need to set extra REQUIRED fields
if (condCodeAsInt == 1000 || condCodeAsInt == 1500)
{
//if it is "new" then remove inputted desc text completely REQUIRED
if (condCodeAsInt == 1000)
{
itemType.ConditionDescription = "";
}
// set UPC value HERE, not in ItemSpecifics.
ProductListingDetailsType pldt = new ProductListingDetailsType();
pldt.UPC = myUpcValue;
itemType.ProductListingDetails = pldt;
//init Item specifics ( and set BRAND and MPN )
itemType.ItemSpecifics = new NameValueListTypeCollection();
//brand
NameValueListType nvBrand = new NameValueListType();
nvBrand.Name = "Brand";
StringCollection brandStringCol = new StringCollection();
brandStringCol.Add(myBrandValue);
nvBrand.Value = brandStringCol;
itemType.ItemSpecifics.Add(nvBrand);
//MPN
NameValueListType nvMpn = new NameValueListType();
nvMpn.Name = "MPN";
StringCollection mpnStringCol = new StringCollection();
mpnStringCol.Add(myMpnValue);
nvMpn.Value = mpnStringCol;
itemType.ItemSpecifics.Add(nvMpn);
}
I have a string with a message containing some fields I want to swap out to actual values
var message = "Hi [CustomerName]. Its [TODAY], nice to see you were born on the [DOB]!";
var mappingCodes = new List<string> {"[CUSTOMER_NAME]","[DOB]",[TODAY]};
var customEmails = new Dictionary<string, string>();
var today = DateTime.Now;
var customers = new List<Customer>()
{
new Customer()
{
FirstName = "Jo",
LastName = "Bloggs",
Email = "jo#bloggs.com",
DOB = "10/12/1960"
}
};
foreach (var customer in customers)
{
var emailMessage = "";
customEmails.Add(customer.Email,emailMessage);
}
What I'm trying to do is loop through each of the customers and take the message replacing any of the mappingCodes with actual codes.
e.g. [Today] Would be the today and CustomerName would be Customer.FirstName + Customer.LastName
There could be 1000's of customers so I need something robust. I'm just not sure how to first check the string contains any of the mappingCodes and then replace them with the desired values.
Any advice?
You could try something like this. String.Format is rather efficient. It also would allow you to format Date.Today, if you want.
var customers = new List<Customer>()
{
new Customer()
{
FirstName = "Jo",
LastName = "Bloggs",
Email = "jo#bloggs.com",
DOB = "10/12/1960"
}
};
foreach (var customer in customers)
{
var emailMessage = String.Format("Hi {0}. Its {1}, nice to see you were born on the {2}!", customer.FirstName, DateTime.Today, customer.DOB);
customEmails.Add(customer.Email,emailMessage);
}
You can use Regex.Replace(string, MatchEvaluator):
var customers = new[] {
new {
Name = "Fred Flintstone",
City = "Bedrock"
},
new {
Name = "George Jetson",
City = "Orbit City"
}
};
string template = "Hello, [NAME] from [CITY]!";
var re = new Regex(#"\[\w+\]"); // look for all "words" in square brackets
foreach (var customer in customers)
{
Trace.WriteLine(
re.Replace(template, m => {
// determine the replacement string
switch (m.Value) // m.Value is the substring that matches the RE.
{
// Handle getting and formatting the properties here
case "[NAME]":
return customer.Name;
case "[CITY]":
return customer.City;
default:
// The "mapping code" is not supported, I just return the
// original substring
return m.Value;
}
}));
}
Obviously the above is just the general approach, you'll have to modify it to support your mapping codes and data structures.