Streamwriter unresponsive to conditionals - c#

I'm trying to test for null values of two particular fields, and if they're null, replace the whitespace with the amount of 0s appropriate for that field. My code below gives no errors, but isn't doing anything and the normal values are being used.
var replace1 = "00";
var replace2 = "0";
var downpay = _Reader[26].ToString();
var preauth = _Reader[28].ToString();
if(downpay == null || downpay == " ") { downpay = replace1; }
if(preauth == null || preauth == " ") { preauth = replace2; }
writer.WriteLine("{0}{1}{2}{3}{5}{6}{7}{15}{16}{17}{18}{19}{20} 0{21}{22}{23}{24}{25}{26}{27}{28}{29}{30}{31}{32}{33}{34}{35}{36}{37} {38}{39}{40}{41}{42}{43}{44}{45}{46}{47}{48}{49} {50}", _Reader[1], _Reader[2], _Reader[3], _Reader[4], _Reader[5], _Reader[6], _Reader[7], _Reader[8], _Reader[9], _Reader[10], _Reader[11], _Reader[12], _Reader[13], _Reader[14], _Reader[15], _Reader[16], _Reader[17], _Reader[18], _Reader[19], _Reader[20], _Reader[21], _Reader[22], _Reader[23], _Reader[24], _Reader[25], downpay, _Reader[27], preauth, _Reader[29], _Reader[30], _Reader[31], _Reader[32], _Reader[33], _Reader[34], _Reader[35], _Reader[36], _Reader[37], _Reader[38], _Reader[39], _Reader[40], _Reader[41], _Reader[42], _Reader[43], _Reader[44], _Reader[45], _Reader[46], _Reader[47], _Reader[48], _Reader[49], _Reader[50], date3);
Update: Fixed the issue using the debugger. The values were \00 and \0, even though when i copy from the field in sql server it's empty.

Related

C#: What is this statement doing? dynObj.#switch == 1 ? true : false

I recently took over some code and came a across a statement that I wasn't sure what it was doing so I decided to post it.
currCarbon.CleanGeneration = (dynObj.#switch == 1 ? true : false);
Since 'dynObj' is a dynamic object holding a json value, is it checking if 'dynObj' contains a 'Switch' key / value?
Thanks for you help!
dynamic dynObj = GetValues();
if (dynObj != null) //json string from API
{
// Read the first record's carbon index
var prevCarbon = _dbContext.WatttimeApilog.OrderByDescending(c => c.CreatedDate).FirstOrDefault();
if (prevCarbon == null) //NO previous carbon value from database
{
//Plug in default values
currCarbon.Percentage = defaultPercent;
currCarbon.CleanGeneration = false;
currCarbon.Rating = defaultRating;
currCarbon.ValidUntil = DateTime.UtcNow;
insertFlag = true;
}
else
{
currCarbon.Percentage = dynObj.percent;
currCarbon.CleanGeneration = (dynObj.#switch == 1 ? true : false);
currCarbon.Rating = Convert.ToByte(dynObj.rating);
currCarbon.ValidUntil = dynObj.validUntil;
}
It's setting CleanGeneration to true or false based on whether or not #switch is equal to one via a ternary operator.
EDIT: The code isn't the most clean and can be shortened to just currCarbon.CleanGeneration = dynObj.#switch == 1;
Linked is docs on the ternary operator:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/conditional-operator

How To show blank datepicker when DB value is null

I've got a SQL DB column for DateTime Birthday on a customer object. The database allows that field to be null, but occasionally our users populate the data (from another system) with 1/1/1900.
I'd like to have my DatePicker field show nothing when the date in the DB is either null or DateTime.Parse("1900-01-01 00:00:00.000"). (It doesn't have to be fully blank, but can have the DatePicker field's standard default of " / / ".
I've been trying this:
dtBirthday.Value = customer.Birthday.HasValue ? customer.CustomerOptions.Birthday.Value : DateTime.Parse("1900-01-01 00:00:00.000");
That works fairly well for the null birthdays, but doesn't allow for the date in customer.Birthday actually being DateTime.Parse("1900-01-01 00:00:00.000").
Update
I did, in fact, google this, and attempted to use
var nullDate = DateTime.Parse("1900-01-01 00:00:00.000");
if (customer.Birthday.Value == nullDate)
{
dtBirthday.Format = eDateTimePickerFormat.Custom;
dtBirthday.CustomFormat = " ";
dtBirthday.Value = DateTime.FromOADate(0);
dtBirthday.Enabled = true;
}
else
{
dtBirthday.Format = eDateTimePickerFormat.Custom;
dtBirthday.CustomFormat = "M/d/yyyy";
dtBirthday.Value = customer.Birthday.Value;
dtBirthday.Enabled = true;
}
//dtBirthday.Value = customer.Birthday.HasValue ? customer.Birthday.Value : DateTime.Parse("1900-01-01 00:00:00.000");
if (customer.Anniversary.Value == nullDate)
{
dtAnniv.Format = eDateTimePickerFormat.Custom;
dtAnniv.CustomFormat = " ";
dtAnniv.Value = DateTime.FromOADate(0);
dtAnniv.Enabled = true;
}
else
{
dtAnniv.Format = eDateTimePickerFormat.Custom;
dtAnniv.CustomFormat = "MM/dd/yyyy";
dtAnniv.Value = customer.Anniversary.Value;
dtAnniv.Enabled = true;
}
//dtAnniv.Value = customer.Anniversary.HasValue ? customer.Anniversary.Value : DateTime.Parse("1900-01-01 00:00:00.000");
It does just about exactly what I want, except that the empty fields are completely disabled, even though I've specifically set them to enabled=true.
If I'm reading your question correctly, I think you want the text field to be empty when the birthday is actually null. Why not just populate it with an empty string:
txtBirthday.Value =
customer.Birthday.HasValue ?
customer.CustomerOptions.Birthday.Value.ToString() :
string.Empty;
After attempting several dozen different methods, none of which really did what I want, it occurred to me that I could just not set the value.
var nullDate = DateTime.Parse("1900-01-01 00:00:00.000");
if (customer.CustomerOptions.Birthday.HasValue && customer.CustomerOptions.Birthday.Value != nullDate)
{
dtBirthday.Value = customer.CustomerOptions.Birthday.Value;
}
if (customer.CustomerOptions.Anniversary.HasValue && customer.CustomerOptions.Anniversary.Value != nullDate)
{
dtAnniv.Value = customer.CustomerOptions.Anniversary.Value;
}

Don't have a nullReferenceException on XML Parsing

I have wrote a c# function in order to parse an XML Stream.
My XML can have several nodes.
Example :
<Stream>
<One>nnn</One>
<Two>iii</Two>
<Three>jjj</Three>
</Stream>
But sometimes, it is :
<Stream>
<Two>iii</Two>
</Stream>
Here is my c# code :
var XML = from item in XElement.Parse(strXMLStream).Descendants("Stream") select item;
string strOne = string.Empty;
string strTwo = string.Empty;
string strThree = string.Empty;
if ((item.Element("One").Value != "")
{
strOne = item.Element("One").Value;
}
if ((item.Element("Two").Value != "")
{
strTwo = item.Element("Two").Value;
}
if ((item.Element("Three").Value != "")
{
strThree = item.Element("Three").Value;
}
With this code, if my Stream is full ( Node On, Two and three), there's no problem! But, if my Stream has only the node "Two", I get a NullReferenceException.
Is there a way to avoid this exception (I cannot change my Stream).
Thanks a lot :)
You should check if item.Element("anything") is null before accessing it's Value property.
if (item.Element("Three") != null && item.Element("Three").Value != "")
You need to do:
if (item.Element("One") != null)
{
strOne = item.Element("One").Value;
}
.Element(String) returns null if an element of the name you requested does not exist.
Checking if value != "" is pointless, because all you are preventing is the reassignment of an empty string to the strOne variable, which is already an empty string. Also, if you really needed to do the empty string check, using String.IsNullOrEmpty(String) method is the preferred way.
Instead of accessing Value property (which raises NullReferenceException if element not exist, as you already know) cast elements to strings. You can use ?? to provide default value for non-existing elements:
string strOne = (string)item.Element("One") ?? String.Empty;
string strTwo = (string)item.Element("Two") ?? String.Empty;
string strThree = (string)item.Element("Three") ?? String.Empty;

Logic to check for Null Value in Multiple Textboxes

Hi guys, probably a simple one.
Using C# .Net 4.0 and Visual Studio 2012 Ultimate.
Got the following code:
string part = "";
part = txtIOpart.Text;
txtBatchCV.Text = txtBatchIO.Text;
txtPartCV.Text = part;
txtExternalCV.Text = Sqlrunclass.SplitSpec_External(part, pg);
txtInternalCV.Text = Sqlrunclass.SplitSpec_Internal();
txtABSCV.Text = Sqlrunclass.SplitSpec_cvABS();
txtOilCV.Text = Sqlrunclass.SplitSpec_OilSeal();
txtBarCV.Text = "*" + Sqlrunclass.SplitInfo_ASno(part, pg) + "*";
txtBarNumCV.Text = txtBarCV.Text;
txtLocnCV.Text = Sqlrunclass.SplitInfo_Location();
txtFitsCV.Text = Sqlrunclass.SplitInfo_Desc();
txtHeightCV.Text = Sqlrunclass.SplitSpec_Height();
txtDiameterCV.Text = Sqlrunclass.SplitSpec_Diameter();
txtCirclitCV.Text = Sqlrunclass.SplitSpec_Circlit();
picTypeCV.Image = ftpclass.Download("CVspecType" + Sqlrunclass.SplitSpec_TypeCV() + ".jpg", "ftp.shaftec.com/Images/TypeJpg", "0095845|shafteccom0", "4ccc7365d4");
if (txtBatchCV.Text == null || txtBatchCV.Text == "")
{
txtBatchCV.Text = "ALL";
}
As you can see at the bottom I'm checking the batch, but I need to check all of the data thats being set by a bunch of methods. Each one will have a different txt output if it sees a null or blank txt. Is there anyway to shorten this code?
Try, txtBatchCV.Text For example
//Just for null
txtBatchCV.Text = (txtBatchCV.Text ?? "ALL").ToString();
//for both null and empty string
txtBatchCV.Text = string.IsNullOrEmpty(txtBatchCV.Text) ? "ALL": txtBatchCV.Text;
You could iterate through all the textboxes
foreach (var txt in form.Controls.OfType<TextBox>())
{
switch(txt.Id){
case "txtBatchCV":
// Do whatever you want for txtBatchCV e.g. check string.IsNullOrEmpy(txt.Text)
break;
}
}
I borrowed the above from here:
How do I loop through all textboxes and make them run corresponding actions from action dictionary?
In response to the comment I got from Tim, I've added a bit more code to explain what you could do. My code example was never meant to be a full solution.
TextBox.Text is never null, it will return "" then. If your methods return null you could use the null-coalescing operator:
string nullRepl = "ALL";
txtExternalCV.Text = Sqlrunclass.SplitSpec_External(part, pg) ?? nullRepl;
txtInternalCV.Text = Sqlrunclass.SplitSpec_Internal() ?? nullRepl;
txtABSCV.Text = Sqlrunclass.SplitSpec_cvABS() ?? nullRepl;
txtOilCV.Text = Sqlrunclass.SplitSpec_OilSeal() ?? nullRepl;
txtLocnCV.Text = Sqlrunclass.SplitInfo_Location() ?? nullRepl;
txtFitsCV.Text = Sqlrunclass.SplitInfo_Desc() ?? nullRepl;
txtHeightCV.Text = Sqlrunclass.SplitSpec_Height() ?? nullRepl;
txtDiameterCV.Text = Sqlrunclass.SplitSpec_Diameter() ?? nullRepl;
txtCirclitCV.Text = Sqlrunclass.SplitSpec_Circlit() ?? nullRepl;
For starters you could use string.IsNullOrEmpty(txtBatchCV.Text), it's a convevience method that basically does what you do in the if check.
You can atleast use one of these methods:
string.IsNullOrEmpty(txtBatchCV.Text)
or
string.IsNullOrWhitespace(txtBatchCV.Text)
I would try something like this:
void SetDefaultIfNull(TextBox txt, string defaultVal)
{
if (string.IsNullOrWhitespace(txt.Text))
txt.Text = defaultVal;
}
Then pass each textbox and the default to the method.

Foreach item changes not preserved outside loop

I have seen this question already but it does not explain it so that I understand what is actually going on. I've been developing for years and never come across this before (though my usage of Linq and Parallel is fairly recent).
My code is:
Parallel.ForEach(databaseMetadata.Rows.Cast<DataRow>(), row => {
var fieldName = row.Item("Name", "");
var field = this.Fields.Where(f => f.Name.ToLower() == fieldName.ToLower()).SingleOrDefault();
if(field != null) { field.Validate(this, connection, row); }
});
Within the field.Validate function it sets a property named 'HasBeenValidated' on the field object to true, however, as soon as I come out of this Parallel.ForEach loop, that property is set back to false. Can someone please explain why this is happening and what I can do to ensure that changes within the loops are persisted outside of the loop.
Edited:
Below is a copy of the code in field.Validate:
internal void Validate(EntityAttribute entity, SqlConnection connection, [AllowNull] DataRow metadata) {
this.HasBeenValidated = true;
var isRequired = this.IsRequired;
var maxLength = this.MaxLength;
var isAutoGenerated = this.IsAutoGenerated;
var dataType = this.member.PropertyType;
var dataTypeAsString = "";
if(metadata != null) {
isRequired = metadata.Item("IsRequired", false);
maxLength = metadata.Item("MaxLength", 0);
isAutoGenerated = metadata.Item("IsAutoGenerated", false);
dataTypeAsString = metadata.Item("DataType", "");
if(dataTypeAsString == this.member.PropertyType.ToSqlServerDataType()) { dataTypeAsString = ""; }
} else {
dataTypeAsString = this.member.PropertyType.ToSqlServerDataType();
}
if(metadata == null || isRequired != this.IsRequired || maxLength != this.MaxLength || isAutoGenerated != this.IsAutoGenerated || dataTypeAsString != "") {
var sql = string.Format((metadata == null ? "ALTER TABLE [{0}].[{1}] ADD" : "ALTER TABLE {0} ALTER COLUMN"), entity.Schema, entity.Name) + " " + this.Sql + ";";
if(!connection.ExecuteCommand(sql, 1)) {
throw new InvalidOperationException("Unable to create or alter column '" + this.Name + "' on table '" + entity.Name + "'.");
}
}
}
The HasBeenValidated property is defined on the field object as:
internal bool HasBeenValidated { get; set; }
Thanks in advance.
Apologies if I've wasted anyone's time but I have figured out the cause of this issue. The this.Fields list is an IEnumerable<> of the field type which is queryable. I thought that this would be better than having a greedy list (since this class has a good number of lists on it). The code for generating the Fields list is:
this.Fields = allProperties
.Select(property => new { Property = property, Field = property.GetCustomAttributes(typeof(FieldAttribute), true).SingleOrDefault() as FieldAttribute })
.Where(info => info.Field != null && (info.Field as ListAttribute) == null)
.Select(info => { info.Field.Member = info.Property; return info.Field; });
What I completely failed to realise was that GetCustomAttributes, rather unexpectedly (from my point of view anyway) regenerates a copy of the attribute class each time it is called.
Had this been a simpler class I might have suspected this sooner, but I was also changing properties in the fields class when setting the Member property (i.e. extracting metadata from the info.Property and setting properties within the field class based on the properties of that class) so when I was looking at the field class in the debugger I could see a lot of the properties had been changed (which mislead me to think it was the same instance of the field class and not a copy).
I really apologise if I've wasted anyone's time and effort in this but hopefully by posting my mistake this can help other people in future who might stumble using the GetCustomAttribute in a similar way inside a non-greedy Linq expression.
It looks like you have a synchronization problem with your DataRow objects - are you sure field.Validate doesn't update the property in the database? And that your databaseMetadata isn't just still sitting on the old data?
The arguments connection, row to field.Validate suggest you might be doing something like that...
Try to use a normal for loop and see what happens. Do you have the same problem?
Can you call databaseMetadata.Rows twice and check is it the same instance or different one.
bool isEquals = ReferenceEquals(databaseMetadata.Rows, databaseMetadata.Rows)
If it's doesn't support immutability I expect it to return a copy of rows each time you access Rows property.

Categories

Resources