Problems with translating special characters (ç) C# -> SQL - c#

Don't often post. but here is a problem that I can't seem to find an answer online.
With this snippet of a C# code:
if (Attributes.TryGetValue("Language", out value)) {
if (value.ToString().Equals("French")) {
cmd.Parameters.AddWithValue("#DEFAULTLANGUAGE","Français");
} else {
cmd.Parameters.AddWithValue("#DEFAULTLANGUAGE","English");
}
I get this stored in the DB Français instead of Français.
Can't find on the MSDN what I need to do to get the correct value.
The languages are stored in their native text, so the ç isn't going to be the only one.
*** Editing original, because replying to thread limits text length***
More details:
Ok, I should have said "Languages are stored in their native text when possible" because yes, it's just a varchar(60) not a nvarchar. I didn't think it would be a problem as ç is in the ASCII varchar list and other records have the value stored correctly.
The query isn't anything special just a standard insert into values query. (not able to display query, but it works. the record is created.) No stored proc, No specific definitions.

LOL
Ok.. There will be a facepalm in here.. but I'm going to post it, because leaving this question unanswered doesn't help people.. (Science should publish their failures too.. anyways)
So, the solutions didn't work, still getting Français instead of Français.
Then I realized that the code file itself, could be in unicode.. and it was..
Converted it to ascii, and it changed the Français to Français.
Corrected the character, and with the below code the problem is fixed!
cmd.Parameters.Add("#DEFAULTLANGUAGE",System.Data.SqlDbType.VarChar,60).Value ="Français";
In the end I wonder why this was a problem in the first place? Ascii is wholly contained within Unicode. Why does it change?

Related

Template class names in weird forms (.NET)

I'm retrieving the names of all the classes in the current runtime in .NET, for the purpose of identifying object and function declarations in sourcecode that's given as input to my program, but templates seem a bit off, for example I've got this among the output:
hashset`1+elementcount[t]
hashset`1+slot[t]
hashset`1+enumerator[t]
which I obtain more or less from this simple code (there's some similar code that gets the referenced assemblies but essentially does the following for each of those instead of the executing assembly).
foreach (Type t in Assembly.GetExecutingAssembly().GetTypes())
{
types.Add(t.ToString().Split('.').Last().ToLower());
}
For now I can of course just Split() the strings to get the first part, before the ` mark, but I was wondering if anyone knows exactly what this might be. The three lines above are consecutive, and a couple more entries for HashSet in my results also have this 1+something thing, so I'm positive it's the actual HashSet class. (note: I'm turning everything to lowercase currently but disabling it doesn't seem to change anything.)
So... anyone know what's this notation? Not sure how to google it, but copy-pasting some lines to Google and enclosing in quotes returns either no results or very random threads that don't end up having the line in them. Thanks in advance.

formatting dates incorrectly, trying to understand the reason

sorry if this question is a little ... strange, but I am a little lost to what is happening and how to control it. What I need to better understand is the following:
I have an ASP MVC application that works with Linq-To-SQL and an MSSQL server. The application is an inside (office only) website, and I am mentioning that so it wont sound that strange when I say that we wanted to ignore browser language, culture, date, whatever... settings and always display the date in the format "dd/MM/yyyy". Always.
So, now that I am testing a specific form in the website I encounter something very, very strange.
The first strange thing is that the date is not displayed on the screen correctly. Let me elaborate, I have a simple view that gets some data, read from the database, inside a model. So, as I fought for sometime with teaching the datetime object to display in a certain way on server level (meaning giving it an attribute like [Display(..)] or [DataType(...)] didn't force the date to look the way I want, so I simply wrote the following:
<input id="BirthDate" name="BirthDate" type="text" value="<%= Model.BirthDate.HasValue ? Model.BirthDate.Value.ToString("dd/MM/yyyy") : "" %>" class="text-box datepicker" />
However, even though I am specifically formatting the date to display "dd/MM/yyyy" in the input, it doesnt. When the browser settings are Dutch, the value inside this box is displayed with 'dd-MM-yyyy'.
I can somehow accept that, the browser is a smart guy(or gal) and identifies that the value in the box is a date and applies formatting according to the selected language settings. I don't know how to tell it not to screw with my dates, but I can get to believe that this is what happens. HOWEVER, what I am finding a lot difficult to accept is that THE Date formatting somehow goes back to the database. This sentance didnt really mean anything so I am explaining again. I have a table that has a few columns, one of them being a varchar(100). Super, and because of some very interesting designing, that field can contain text, dates and whatever.
So, because the field is a string, and later on I simply display it in a paragraph and dont need to do the whole dance of casting it to a DateTime object and then formatting it back when it gets in the view (which works so perfectly as I previously mentioned) I simply save it in the table in the correct format (dd/MM/yyyy).
Yea, but not really. My code would look like that:
var date = DateTime.Now;
db.EmployeeHistory log = new EmployeeHistory();
log.ActionType = 1;
log.EmployeeId = 1671;
log.At = date;
log.Context = "A TEST";
log.ObjectTitle = "Who cares";
log.EmployeeHistoryChangesSets.Add(new EmployeeHistoryChangesSet()
{ PropertyName = "TEST PROPERTY", NewValue = date.ToString("dd/MM/yyyy"), OldValue = date.ToString() });
dataContext.EmployeeHistories.InsertOnSubmit(log);
dataContext.SubmitChanges();
This is a of course a test, one that didnt make me happy at all. Because, if you are paying attention, there is a field in the database which is mapped to a string (varchar(...)) and then I am taking the Date, make it a string with the .ToString() method while formatting it into a "dd/MM/yyyy" format. So I am not using dates (well I am using a Date object to get the date, but I am converting it to a string) I am using only strings.
And somehow, for some reason that is truly escaping me, the string/date is saved in the database in the format: 'dd-MM-yyyy'. I really didnt expect it to behave in such a way. At first I was going to accept my fate, even though I was having a really hard time accepting that the database will take the liberty to format my input even though IT IS a string.
So, further testing showed me that the Date.ToString("dd/MM/yyyy") method actually returns the date in 'dd-MM-yyyy', depending on the browser language settings. Meaning that if I change my settings and it works correctly again ("dd/MM/yyyy").
So, my question is, what am I missing? Why is the .ToString() method not formatting the date correctly? Is my analisys correct or am I up and to the right on this one? If there is a good reason for that (even though I cant come up with one), should I just create my own extension method for DateTime class and implement the formatting mannualy or is there a better way?
I am really sorry for the long post (again). I would appreciate some clarity, as the whole project will behave this way. Thanks in advance

Incorrect Encoding Causing Problems with DB Query

It's late and my caffeine IV is running low so my mind is mush and I'm having problems finding a solution to what I think is a simple encoding problem (which I have almost no experience dealing with).
I have a DB using EF6 Code First and everything seems to work well until I copy some text from a website forum contained within a codeblock. I checked the header and it's supposedly encoded in UTF-8.
I essentially take this text, split it to an array of strings and check the DB for a record matching the string in each line. Everything was going well until I hit a problem with a string "Magnеtic" not matching up to anything in my DB table yet when I went into the SQLMS and queried the table with LIKE '%Magnеtic%' I got a result.
I dropped the text from the website into Notepad++ with the text from the DB query and saw that they look equal:
Magnеtic
Magnеtic
Then, I changed the encoding to ANSI and it showed:
Magnetic <--From DB
Magnеtic <--From website
A tiny light bulb went on in my head but my attempts to remedy this issue has failed.
I've tried using various methods but I think it's my fried brain attacking the problem with the wrong tools:
string.compare(a, b) == 0
string.equals(a, b)
string.ToUpperInvariant()
and probably a few others that I can't remember.
So now you know what my issue is and I feel this is such a simple problem to fix but, like I said, I'm fried and now need some community help.
I'm not a professional coder, more a hobbyist so I may not be using best practices or advanced techniques to do some things.
Edit:
Today I did some more searching and found a couple of methods that didn't work.
private string RemoveAccent(string txt)
{
byte[] bytes = Encoding.GetEncoding("Cyrillic").GetBytes(txt);
return Encoding.ASCII.GetString(bytes);
}
This one appears to remove the accented characters of the Cyrillic encoding. The result wasn't as expected but it DID have an effect.
Results:
Magn?tic <- Computer interpretation
Magnetic <- Visual representation
I also tried:
private string RemoveAccent2(string txt)
{
char[] toReplace = "àèìòùÀÈÌÒÙ äëïöüÄËÏÖÜ âêîôûÂÊÎÔÛ áéíóúÁÉÍÓÚðÐýÝ ãñõÃÑÕšŠžŽçÇåÅøØ".ToCharArray();
char[] replaceChars = "aeiouAEIOU aeiouAEIOU aeiouAEIOU aeiouAEIOUdDyY anoANOsSzZcCaAoO".ToCharArray();
for (int i = 0; i < toReplace.Count(); i++)
{
txt = txt.Replace(toReplace[i], replaceChars[i]);
}
return txt;
}
This method didn't provide any changes.
What can help in these cases is to copy-paste the character into google. In this case, the results point to the Wikipedia article about the letter Ye in Cyrillic, which looks exactly like E in the Latin alphabet, but has different encoding in Unicode.
This means the results you're getting are correct: the string “Magnеtic” looks exactly the same as “Magnetic” (at least using common fonts), but it's actually a different string.

C#: Dateformat in C# for Inserting to sql server

I have a textbox with date format dd/MM/yyyy that I want to convert to the format yyyy-MM-dd to insert it into a database.
I tried
Convert.DateTime/DateTime.ParseExact
but it always give me the system's default date format.
I don't know any other method to convert it in C#...
You shouldn't be converting it to a string at all to insert it into your database. (I'm surprised at all the other answers which are recommending this approach.)
Instead, you should be using parameterized SQL, and set the value of the parameter to the DateTime value you've got. You should be using parameterized SQL anyway to avoid SQL injection attacks, and to keep your code and data separate. The fact that it avoids unnecessary string conversions (each of which is a potential pain point) is yet another benefit.
This part of your question suggests you've got a fundamental misconception:
I used Convert.DateTime/DateTime.ParseExact it always give me system date format.
Those methods will give you a DateTime. A DateTime doesn't have a format. When you call ToString you just get the default format for the current culture, but that's not part of the value. It's like with numbers - 16 and 0x10 are the same number, and the int doesn't "know" whether it's in decimal or hex; it's a meaningless concept.
All of this goes beyond your immediate problem, towards trying to keep your code base clean in terms of types. You should keep data in its most appropriate form for as much of the time as you possibly can, and make sure you understand exactly what that data means at all points. Conversions to other types (such as strings) for communication should be done only at API/system boundaries, and avoided even there if possible (e.g. using parameterized SQL as in this case).
There are many methods but none so useful and logical than using Parametrized SQL. Here's the Wikipedia page! For more information on Parametrized SQL statements, Visit this Coding Horror page!
There is actually no need to change it. This is just the display format, but the 'DateTime' object inside stays the same. Depending on how you want to insert, you can just use:
string dateValue = DateTime.Now.ToString("yyyy-MM-dd");
And insert this in your query string.
EDIT
But as Jon Skeet commented, building your query string manually like this should never be done. A cleaner approach like parameterized SQL or utilizing NHibernate should be your first concern.
Hope this works!
DateTime variable= Convert.ToDateTime(your date);
You can format it like this:
string sDateTime = Convert.ToDateTime(txtTextBox.Text).ToString("yyyy-MM-dd");
Edit
There are many ways to skin a cat when it comes to preparing information for entry into a database. My solution here answers the OP directly, however I very much acknowledge that there are better ways to do this.
I'd suggest reading through Jon Skeet's post on this page as well, as he raises some extremely valid points regarding the approach of the OP.
Hope that helps.

C# parse string "0" to integer

I have a new laptop at work and code that worked earlier in the week does not work today.
The code that worked before is, simplified:
while (dr.Read())
{
int i = int.Parse(dr.GetString(1))
}
Now it fails when the database value is 0. Sometimes, but not reliably, this will work instead:
while (dr.Read())
{
int i = Convert.ToInt32(dr["FieldName"]))
}
Am I missing something stupid?
Oddly enough, ReSharper is also having tons of weird errors with the same error message that I am getting with the above code: "input string was not in the correct format." (Starts before I even load a project.)
Any ideas? Anyone having any SP issues? I did try to make sure all my SPs were up-to-date when I got the machine.
EDIT: I understand how to use Try.Parse and error-handling. The code here is simplified. I am reading test cases from a database table. This column has only 0, 1, and 2 values. I have confirmed that. I broke this down putting the database field into a string variable s and then trying int.Parse(s). The code worked earlier this week and the database has not changed. The only thing that has changed is my environment.
To completely simplify the problem, this line of code throws an exception ("input string was not in the correct format"):
int.Parse("0");
EDIT: Thanks to everyone for helping me resolve this issue! The solution was forcing a reset of my language settings.
A possible explanation:
Basically, the problem was the
sPositiveSign value under
HKEY_CURRENT_USER\Control
Panel\International being set to 0,
which means the positive sign is '0'.
Thus, while parsing the "positive sign
0" is being cut off and then the rest
of the string ("") is parsed as a
number, which doesn't work of course.
This also explains why int.Parse("00")
wasn't a problem. Although you can't
set the positive sign to '0' through
the Control Panel, it's still possible
to do it through the registry, causing
problems. No idea how the computer of
the user in the post ended up with
this wrong setting...
Better yet, what is the output of this on your machine:
Console.WriteLine(System.Globalization.NumberFormatInfo.GetInstance(null).PositiveSign);
I'm willing to bet yours prints out a 0... when mine prints out a + sign.
I suggest checking your Control Panel > Regional and Language Options settings... if they appear normal, try changing them to something else than back to whatever language you're using (I'm assuming English).
I think it's generally not considered a good idea to call Convert.ToInt32 for the value reading out of database, what about the value is null, what about the value cannot be parsed. Do you have any exception handling code here.
Make sure the value is not null.
Check the value can be parsed before call Int32.Parse. Consider Int32.TryParse.
consider use a nullable type like int? in this case.
HTH.
Edit:
#Mike's response made me think that is extremely odd behavior and a simple google search yielded this result: int.Parse weird behavior
An empty string would also cause this issue.
You could check for dbnull before parsing, also it is good to validate parsed data.
You could use a default value and TryParse..
int i = -1;
if(!int.TryParse(dr["MyColumn"] as string, out i))
//Uh Oh!
Edit:
I posted this as a comment in #Chris' answer, but if the sql datatype is int then why not just use the GetInt32 method on the DataReater instead of retrieving it as a string and manual parsing it out?
Are you sure it's "0" and not "null"? What exception do you get?
EDIT:
Just out of curiosity, if it is really faulting on int.Parse("0"), can you try int.Parse("0", CultureInfo.InvariantCulture);?
Otherwise, post your query. Any joins?
you should check dr["FieldName"] != DBNull.Value and you should use TryParse if it passes the DBNull test...
if ( dr["FieldName"] != DBNull.Value )
{
int val = 0;
if ( int.TryParse( dr["FieldName"], out val ) )
{
i = val;
}
else
{
i = 0; // or some default value
}
}
I have seen this issue crop up with .NET Double class, parsing from string "0" as well.
Here's the really wacky part: you can get past the issue by using a different user account to run the program, and sometimes if you destroy and re-create the current user account on the machine, it will run fine.
I have yet to track this down, but you might get past it this way at least.
This is way out of left field, but check your localization settings. I had a number of "input string was not in a correct format" when I moved a web site to a Canadian server. The problem was in a DateTime.Parse method, and was fixed by setting the culture to "en-US".
Yes, your situation is different — but hey, you never know.
are you checking for null ?
if(!dr.IsNull("FieldName")){
int i = Convert.ToInt32(dr["FieldName"]))
}

Categories

Resources