Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal
C#
code:
string list = System.IO.File.ReadAllText(@"list.txt");
            string[] lines = list.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
            string address;
            address = textBoxUrl.Text;

            // Add http if no URL prefix is found
            foreach(string listnumber in lines)
            {   
                if (!address.StartsWith("http://") && !address.StartsWith("https://"))
                {
                    address = "http://" + address + listnumber;
                }
                else
                address = address + listnumber;

                richTextBoxOutput.Text += "\n" + address;
            }
Anyone see any reason for this not to work? I'm trying to create a simple proof of concept that will read a URL from a text box, and then append each line from a text file to the end of the URL, and then simply display it to the richTextBox control.

Also when I'm using HttpWebRequest and HttpWebResponse, if I get a 404 the program chokes out and closes. I've been trying to use:
code:
myHttpWebResponse.StatusCode != HttpStatusCode.NotFound 
but it still likes to throw an exception. Any ideas how I could get around this? I'm trying to simply request a page from an online server, and then analyze the header/outputs (503, 404, 100, etc).

Thanks.

Adbot
ADBOT LOVES YOU

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Ithaqua posted:

[edit]
Now I see...

Declare the address variable in the scope of your foreach.

Worked perfectly, thank you :).

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal
I'm running into a bit of trouble with a multi-threaded program. I'm getting completely random results (+- 100) with this bit of code:

code:
                Thread.Sleep(400);

                file.Close();

                lock (this)
                {
                    string parsedList = System.IO.File.ReadAllText(@"lists\templist.txt");
                    string[] parsedLines = parsedList.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
                    try
                    {

                        foreach (string listnumber in parsedLines)
                        {
                            // Display Parsed Lines for end use
                            Thread.Sleep(1);
                            // Call object data from function start
                            address = data.ToString();
                            // Add http if no URL prefix is found
                            if (!address.StartsWith("http://") && !address.StartsWith("https://"))
                            {
                                address = "http://" + address;
                            }

                            if (!address.EndsWith("/"))
                                address = address + "/";

                            // Append data from list
                            address = address + listnumber;
                            address.Trim();

                            [b]finishedHits++;[/b]
                            //ChangeProgressBarMax(progressBarMax);

                            //Thread processThread = new Thread(delegate() { Process(address + " " + listIndex); });
                            //processThread.Start();
                            ThreadPool.QueueUserWorkItem(new WaitCallback(Process), (address + " " + listIndex));
Here's the -very- beginning of the Process thread

code:
 private void Process(object data)
        {
            string getDataInfo = data.ToString();
            string[] dataInfo = getDataInfo.Split(new string[] { " " }, StringSplitOptions.None);

            string address;
            address = dataInfo[0];
            address.Trim();
            string listIndex = dataInfo[1];
            countAllHits++;
            ChangeList(countAllHits, int.Parse(listIndex), 2);
            Thread.Sleep(1);
Variables not matching up: countAllHits, finishedHits

Does anyone have an idea why countAllHits will end up being 9900 +-, when it should be 10,000 on the dot? It's totally screwing up my status update so I don't know when it's finished running :gonk:

e(clarify): finishedHits will be 10,000, countAllHits will not be 10,000. Nearly immediately after finishedHits is incremented, a new threadpool call is made, which nearly immediately increments countAllHits as well.

Knyteguy fucked around with this message at 04:15 on Feb 16, 2012

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Eggnogium posted:

Not too familiar with C# threading so I could be wrong, but I think you need to lock around "countAllHits++;". It seems like a single operation but it's actually several (loading the value, incrementing it, and storing it back), so if a thread gets interrupted in the middle of those three steps the value will end up being wonky.

Edit: You should really lock around any operation where a thread changes a variable accessible by other threads. Some classes have this locking baked into their methods but definitely not the primitive value types.

Thanks that did it :woop: I'll have to lock down the other vars as well, I'm sure that's been causing some issues that I just haven't noticed yet.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Sedro posted:

No offense but it looks like you're totally over your head. That code you posted is full of horrors. You should really learn the threading concepts instead of just sprinkling mutex locks everywhere.

The Interlocked class has methods to perform increment atomically without locking.

Thanks I'll take a look at that. I've also used a bit of Parallel.ForEach but the program actually ended up slowing down. Because this is my first 'real' program, I'm not very worried about anything other than it working (which it is, besides some thread issues).

If you think this part is bad though, you would probably get a headache from my regex list parsing :psyduck:.

However besides the Interlocked class, do you mind mentioning a few of these 'horrors' so I can see where I can improve? If you get a chance.

Knyteguy fucked around with this message at 05:29 on Feb 16, 2012

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal
Sup Goons, I'm building a portfolio website of all my work because my job pays me $12.50 an hour 20 hours a week to program software, program web, design web, computer troubleshooting, and manage a website. So... I figured it might be time to move onto greener pastures :unsmith: Anyway while I figure out what position I might be applying for, I'm trying to clean up some of my slightly older program code to conform with better practices I've learned since.

Going back, I would have written this top function buttonParseProcommD2M_Click to work with an unlimited amount of systems by using sender, but I didn't. Barring that, does anyone see anything that screams "oh poo poo this is terrible!"? It runs wonderfully daily in a commercial environment, but I would like to move up a tier in the programming business if possible. (This is just 2 functions I used as a code sample, not the entire program (obviously...))

Formatting got a little screwed up, and I had add some return characters to stop it from breaking tables.

code:
        private void buttonParseProcommD2M_Click(object sender, EventArgs e)
        {

            if (procommFile.Text == null || !procommFile.Text.EndsWith(".xls"))
            {
                MessageBox.Show("Please select a valid report file first!", "Error", MessageBoxButtons.OK, 
		MessageBoxIcon.Error);
            }
            else
            {
                // Ensure the program does not run multiple times unnecessarily from user error
                buttonParseProcommD2M.Hide();

                progressBarD2M1.Show();

                statusTextD2M.Text = "Parsing...";

                string thisSystem = "D2M";

                // Start Parsing
                openReport(thisSystem);
            }
	}

	private void openReport(string whatSystemIsIt)
        {
            //whatSystemIsIt is to identify if it is Amazon, LPSD, etc.

            // Start Excel
            Excel.Application xlApp;
            Excel.Workbook xlWorkBook;
            Excel.Worksheet xlWorkSheet;
            object misValue = System.Reflection.Missing.Value;

            xlApp = new Excel.Application();
            xlWorkBook = xlApp.Workbooks.Open(textBoxReportFile.Text,
		 0, 
		 true, 
		 5, "", "", 
		 true,
		 Microsoft.Office.Interop.Excel.XlPlatform.xlWindows,
		 "\t", false, false, 0, true, 1, 0);
            xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

	    // Parse Procomm data into an array to manipulate
	    // Consider using 'Task Parallel' in future update
            for (int i = 9; i < 12000; i++)
            {
                // Excel Columns A & C from ProComm represent SKU & Inventory Quantity
		// Start with excel columns A(i), C(i) and move on
                string columnA = "A" + i;
                string columnC = "C" + i;

                // Update status bar, update per 10 to keep graphics update smooth on a single thread app
                if (i % 10 == 0)
                {
                    if (whatSystemIsIt == "Amazon")
                    {
                        progressBarAmazon.Value = i;
                    }
                    else if (whatSystemIsIt == "LPSD")
                    {
                        progressBarLPSD.Value = i;
                    }
                    else if (whatSystemIsIt == "D2M")
                    {
                        progressBarD2M.Value = i;
                    }
                }

                // Ensure that we don't try to bind a null/blank cell
                if (xlWorkSheet.get_Range(columnA, columnA).Value != null && 
		xlWorkSheet.get_Range(columnC, columnC).Value != null)
                {
                    // Put the found SKU cell data into a workable format
                    string procommSkuAndInventory = xlWorkSheet.get_Range(columnA, columnA).Value2.ToString();

                    // Only proceed if the cell SKU has a "-" (All products from the past 17 years have dashes)
		    // Get data
                    if (procommSkuAndInventoryCount.Contains('-'))
                    {
			// Add inventory data
                        procommSkuAndInventory += '\t' + xlWorkSheet.get_Range(columnC, columnC).Value2.ToString();
                        // Store excel data in the global array from earlier
                        procommSkuAndInventoryArray[i] = procommSkuAndInventory;
                    }
                }
            }

            // Clean up
            xlWorkBook.Close(true, misValue, misValue);
            xlApp.Quit();

            releaseObject(xlWorkSheet);
            releaseObject(xlWorkBook);
            releaseObject(xlApp);

            // Appropriate labels to give feedback to users 
            // Hide all progress bars since the procomm file does not need to be run for each system
            //Amazon
            labelAmazonParseProcomm.Text = "2) Parse Pro Comm Report";
            labelAmazonParseProcomm.ForeColor = Color.Silver;
            progressBarAmazon.Visible = false;
            progressBarAmazon.Value = 0;
            pictureBoxCheckBoxAmazon1.Visible = true;

            //LPSD
            labelLPSDParseProcomm.Text = "2) Parse Pro Comm Report";
            labelLPSDParseProcomm.ForeColor = Color.Silver;
            progressBarLPSD1.Visible = false;
            progressBarLPSD1.Value = 0;
            pictureBoxCheckBoxLPSD1.Visible = true;

            //D2M
            labelD2MParseProcomm.Text = "2) Parse Pro Comm Report";
            labelD2MParseProcomm.ForeColor = Color.Silver;
            progressBarD2M.Visible = false;
            progressBarD2M.Value = 0;
            pictureBoxCheckBoxD2M1.Visible = true;

        }

Knyteguy fucked around with this message at 21:31 on Sep 25, 2012

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

CapnAndy posted:

You're doing a slightly strange mixture of using .Show() and .Hide() vs. directly setting .Visible, I don't see where you show the button after you hid it at the start of the click event, and for personal preference I'd set .Enabled to false rather than hiding the button; greying it out is more visually understandable as "okay, you can still use this, just not now" whereas things disappearing when you click them can be a little startling.

That's a great idea, I think I'll implement that thanks :).

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Ithaqua posted:

Yes. Do not submit this code to a potential employer as it is.

Here's my short list, without digging into the actual functionality:
  • You're not separating your concerns. Presentation logic and application logic should not be mixed. This is a huge problem -- it shows that either you lack a fundamental understanding of object oriented programming (which is bad), or that you don't give a poo poo about doing it right (which is worse).
  • Where are your unit tests? How do you know your application functions properly? How do you know that you're not breaking existing functionality when making changes? Having unit tests earns you points with a lot of employers. It certainly does with me!
  • You do not follow Microsoft's naming conventions. I'm a stickler for this one, especially in sample code. Other people will tell you it doesn't matter, but my position is that Microsoft took the trouble to create a style guide, it makes a lot of sense, and there are lots of tools that can help enforce it. If you have a good reason for not following the guide and can articulate it and convince me, that's fine. If you don't have a good reason, then I chalk it up to sloppiness and/or not giving a poo poo.

Question: Does your application even update the progress bar visually? You're blocking the UI thread as far as I can tell.

Thanks I'll make some changes - I want it to be as well done as possible.

MVC (this is MVC related right?) is something I've only briefly touched upon. It sounds like I should probably do some more reading on it and understand what it actually represents, and how to implement it correctly.

Unit tests I've never done. I just found a basic tutorial for VS/C# so I'll look into this.

Naming conventions... I'll read what the standard is. I'm certain I can learn this fairly quickly.

Question: Does your application even update the progress bar visually? You're blocking the UI thread as far as I can tell.

It does on this sample code. It doesn't in a second part of the program (which I've been meaning to fix for my co-worker in an update) that also uses a progress bar. I've gotten my feet wet with multi-threading/task parallel so it sounds like I should just update it in the program and the sample code.

Thank you for the input :).

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Hughmoris posted:

Since the OP hasn't been updated in 3 years, are there any new recommended books for people looking to pick up C# as a first language?

This was a pretty good book in my opinion: http://www.amazon.com/Stephens-Prog...24-Hour+Trainer

It walks you through how to use and setup visual studio, building program UIs, creating functions, manipulating variables, accessing the printer, making responsive dialogs, etc and they give you 1 main exercise and 4-5 extra exercises at the end of every chapter. At the end of the book you'll have written 1 pretty complicated program, and 40-50 main and extra programs.

The author writes in a very comfortable manner that makes it all easy to follow even if you've never learned a language. He doesn't just drop a shitload of code on you and expect you to copy it. Often he'll explain concepts and then challenge you to implement the knowledge yourself (though you can download exercise code from his website if you get stuck). Obviously you won't pick it all up in 24 hours, so the title was my only complaint about it

It will not cover more advanced things like multi-threading/task paralleling, but it's a great way to get into the language.

e: clarification

Knyteguy fucked around with this message at 23:55 on Sep 29, 2012

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Ithaqua posted:

That book looks like it's terribly organized. How can you spend 10 chapters talking about Winforms GUI stuff before introducing the concept of variables?

I wish Jon Skeet would get around to writing his book for beginners, because then there would be a book that I could wholeheartedly recommend.

I think he pretty much just explains how to actually build the UI, and then goes into the code side of it. I remember being a bit frustrated reading the book because I simply wanted to make a basic calculator and wasn't familiar with how to declare variables in C# :arghfist:. All-in-all it was extremely helpful for someone who had never touched Visual Studio though.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Ithaqua posted:

Yes. Do not submit this code to a potential employer as it is.

Here's my short list, without digging into the actual functionality:
  • You're not separating your concerns. Presentation logic and application logic should not be mixed. This is a huge problem -- it shows that either you lack a fundamental understanding of object oriented programming (which is bad), or that you don't give a poo poo about doing it right (which is worse).
  • Where are your unit tests? How do you know your application functions properly? How do you know that you're not breaking existing functionality when making changes? Having unit tests earns you points with a lot of employers. It certainly does with me!
  • You do not follow Microsoft's naming conventions. I'm a stickler for this one, especially in sample code. Other people will tell you it doesn't matter, but my position is that Microsoft took the trouble to create a style guide, it makes a lot of sense, and there are lots of tools that can help enforce it. If you have a good reason for not following the guide and can articulate it and convince me, that's fine. If you don't have a good reason, then I chalk it up to sloppiness and/or not giving a poo poo.

Question: Does your application even update the progress bar visually? You're blocking the UI thread as far as I can tell.

So after re-reading this I decided I'm probably just going to rewrite most of my inventory program tomorrow. I've never actually done unit tests, so I'm going to try a test-driven design with multi-threading and see how it goes.

I'm still not very familiar with OOP principals (I'm not formally taught and usually just try different things until they work), do you or does anyone else have a good book I could read on the subject? I feel a bit over my head with best practices regarding this.

Anyway here's another sample of code that I'm hoping is good as-is.
code:
private string parseLinks(string url)
{
	// Our HTML page has &amp; instead of &, which won't work for URLs
	url = url.Replace("&amp;", "&");
	if (!url.StartsWith("http"))
	{
		url = "http://REMOVED FOR EMPLOYER PRIVACY.com" + url;
	}
	string formattedUrl = url;
	HtmlAgilityPack.HtmlWeb htmlWeb = new HtmlAgilityPack.HtmlWeb();
	HtmlAgilityPack.HtmlDocument doc = htmlWeb.Load(formattedUrl);
	List<string> hrefTags = new List<string>();
	// Pull links from HTML
	foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]"))
	{
		if (link.Attributes["href"] != null)
		{
			HtmlAttribute linkElement = link.Attributes["href"];
			hrefTags.Add(linkElement.Value);
		}
	}
	
	for (int i = 0; i < hrefTags.Count(); i++)
	{
		if (hrefTags[i].Contains(".jpg") || hrefTags[i].Contains(".jpeg") || hrefTags[i].Contains(".tif"))
		{
			// Get the SKU code from the image
			string productCode = hrefTags[i];
			productCode = productCode.Replace(".jpg", "");
			productCode = productCode.Replace(".tif", "");
			productCode = productCode.Replace(".jpeg", "");
			// Get it ready for Excel: i.e.: 428-2006;[url]http://linktoimage.com/428-2006.jpg\n[/url]
			skuTextBox.AppendText(productCode + ";" + formattedUrl + hrefTags[i].ToString() 
				+ System.Environment.NewLine);
			// Make sure we don't follow this link later
			hrefTags[i] = null;
		}
		else
		{
			if (!hrefTags[i].StartsWith("?") && hrefTags[i] != "/")
			{
				// this is a link, add this to list so we can check it later for more images
				hrefTags[i] = formattedUrl;
			}
		}
	}
	return null;
}
It's not the most complicated thing, but if anyone would mind giving just a quick critique that would be great (I won't ask again for awhile:shobon:)

E: had to remove html special codes

Knyteguy fucked around with this message at 08:05 on Sep 30, 2012

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Ithaqua posted:

* The code itself is meaningless. You're providing no background on why this code exists. What problem were you solving? Why did you approach it that way? Did you try any other approaches?

* The method name sucks. It's named "parseLinks", but it's doing a hell of a lot more than that. It probably should be two (or more) methods, each descriptively named. Don't be afraid to make really long method names, as long as it's descriptive.

* Why are you creating a new variable here?
code:
if (!url.StartsWith("http"))
{
	url = "http://REMOVED FOR EMPLOYER PRIVACY.com" + url;
}
string formattedUrl = url;
Just keep using url.

* Why does the method always return null? That makes no sense. If it doesn't return anything, it should be void.

* That for loop is looking pretty suspect. First off, be careful about using the Count() method -- it has to iterate over the entire collection to get that count. List<T> has a Count property, which you should be using in this case.

* This code makes no sense whatsoever:
code:
// Make sure we don't follow this link later
hrefTags[i] = null;
* This code also makes no sense:
code:
if (!hrefTags[i].StartsWith("?") && hrefTags[i] != "/")
{
    // this is a link, add this to list so we can check it later for more images
    hrefTags[i] = formattedUrl;
}
What do you mean "check it later"? There is no later in this method. It's pointless.

Thanks Ithaqua. I'll be going over this tomorrow and seeing what I can get from it. I made this program back in April and need to go over all of the code to figure out what it's doing again apparently. On that note I probably need better comments too.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Okita posted:

Here's a slightly more concise(but more esoteric and cheeky) way of essentially doing what you did. Just trying to give you some ideas about ways you can go about doing this kind of stuff:
code:
//...

url = url.Replace("&amp;", "&");
if (!url.StartsWith("http"))
{
    url = "http://REMOVED FOR EMPLOYER PRIVACY.com" + url;
}

var validExtensions = new List<string> {".jpg", ".jpeg", ".tif"};
var links = GetLinks(url, link => validExtensions.Exists(link.EndsWith));

foreach (string link in links)
{
    string productCode = link.Substring(0, link.LastIndexOf('.'));
    skuTextBox.AppendText(string.Format("{0};{1}{2}", productCode, url + link, Environment.NewLine));
}

//...

private List<string> GetLinks(string url, Predicate<string> condition = null)
{
    var htmlWeb = new HtmlAgilityPack.HtmlWeb();
    var doc = htmlWeb.Load(url);

    var links = new List<string>();
    
    foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]"))
    {
        if (link.Attributes["href"] != null)
        {
            string value = link.Attributes["href"].Value;
            
            if ((condition != null) && (! condition.Invoke(value)))
            {
                continue;
            }

            links.Add(value);
        }
    }
       
    return links;
}

Thank you for the example. I hadn't thought of using a list for the extensions :). The rest of the code is very good as well, I'm going to check out the link you posted as well.

Thanks everyone else too, the help is appreciated.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal
Does anyone know of a good random number generation library for C#? I'm thinking of creating a basic slot machine. I know the best random number generators come with some hardware, but that's pretty much beyond the scope of what I want to do.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Ithaqua posted:

System.Random?

The biggest complaint people have about the provided random number generator comes from misusing it. Don't be a doof and keep instantiating a new instance of Random. Just do something like this:
code:
    public class Program
    {
        private static readonly Random randomNumberGenerator = new Random();

        public void Foo()
        {
            var randomNumber = randomNumberGenerator.Next();
        }
    }

Hm alright thank you; I suppose you're right - it should be sufficient. http://www.extremeoptimization.com/Documentation/Statistics/Random_Numbers/Random_Number_Generators.aspx looks awesome but I'm not going to pay $1,000 for a project I'm doing for fun.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal
Anyone that wouldn't mind giving a quick code review? I've never conformed with separating logic and view before, so I tried to do that here without going too crazy on functions. Credit to Ithaqua for the random code.

code:
private static readonly Random randomNumberGenerator = new Random();

        public int GenerateRandomNumber()
        {
            var randomNumber = randomNumberGenerator.Next(100);
            return randomNumber;
        }

        private void ShowMessage(string title, string message)
        {
            MessageBox.Show(message, title);
        }

        private void GetBets(object sender, EventArgs e)
        {
            // Get bet button values
            Button betButton = (Button)sender;
            string betButtonText = betButton.Text;

            int currentBet = 0;

            if (betButtonText.Contains("$1"))
            {
                currentBet = 1;
            }
            else if (betButtonText.Contains("$5"))
            {
                currentBet = 5;
            }
            else //Maxbet
            {
                currentBet = 25;
            }

            IncrementBetAndDecrementMoney(currentBet);
        }

        private void IncrementBetAndDecrementMoney(int currentBet)
        {
            string totalBetString = betLabel.Text.Replace("Bet: $", "");
            string totalMoneyString = moneyLabel.Text.Replace("Money: $", "");
            int totalBet = Int32.Parse(totalBetString);
            int totalMoney = Int32.Parse(totalMoneyString);

            if (totalMoney - currentBet < 0 || totalMoney == 0)
            {
                ShowMessage("Error", "You do not have enough money to make this bet!");
            }
            else
            {
                if (currentBet + totalBet > 25)
                {
                    currentBet = 25 - totalBet;
                    ShowMessage("Information", "Your total bet was above $25.00, setting your bet to $25.00");
                }

                moneyLabel.Text = "Money: $";
                moneyLabel.Text += (totalMoney - currentBet).ToString();

                betLabel.Text = "Bet: $";
                betLabel.Text += (totalBet + currentBet).ToString();
            }
        }
        
        private void SpinTheReels(object sender, EventArgs e)
        {
            string totalBetString = betLabel.Text.Replace("Bet: $", "");
            int totalBet = Int32.Parse(totalBetString);

            if (totalBet != 0)
            {

                reel1.Text = GenerateRandomNumber().ToString();
                reel2.Text = GenerateRandomNumber().ToString();
                reel3.Text = GenerateRandomNumber().ToString();

                ResetTheBetLabelToZero();
            }
            else
            {
                ShowMessage("Error", "You must make a bet before playing! :)");
            }
        }

        private void ResetTheBetLabelToZero()
        {
            betLabel.Text = "Bet: $0";
        }
Would using the simple ShowMessage() function be considered mixing logic and view? GenerateRandomNumber() could also be renamed to GetNextRandomNumber() to clear it up a bit. Thanks!

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal
Anyone mind doing a quick code review? https://github.com/Noppadet/LPMigrate/blob/master/LPSD%20Product%20Migration/Form1.cs

E: This code isn't completely finished just in case you're wondering.

Knyteguy fucked around with this message at 08:38 on Dec 27, 2012

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal
Cross posting from Version Control:
Using TFS and I keep running into this error, anyone have any idea what's up? I tried clearing the cache, but this is like the third time it's happened.

"The local version table for the local workspace XXX:XXX@EMAIL.com could not be opened. The workspace version table contains an unknown schema version."

It's incredibly annoying and hampering development time by quite a bit.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Ithaqua posted:

Delete the workspace.

Thanks; I've tried that and it works but it ends up happening again within a day for some reason.

It sucks because I end up losing commits/pushes (which what the hell this shouldn't happen), -and- have to download 16k files every single time from the server :suicide:.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal
e ^:

Thanks I'll check. I'll see if a server workspace will work better, too.

I had installed VS2012 Update 2 yesterday, but every time I would run the project (web project) it would only say "Server is busy". I did a system restore and the error went away. Is VS2012 still reaching maturity?

Maybe I'll try again just before closing up today. I'll check what TFS version is installed.

epalm posted:

If my version control software "lost" some commits/pushes, even once, I would throw it out. It's like a dog that bites someone, gotta put 'er down.

I have a bad feeling in the pit of my stomach just thinking about it :(

Unfortunately my boss is pretty sold on it; I'd prefer a bitbucket repo even though some of the features of TFS are pretty nice.

Knyteguy fucked around with this message at 21:12 on Jun 7, 2013

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Ithaqua posted:

I've had no problems with VS2012 (or TFS2012, for that matter), other than some minor usability complaints (the VS2012 test runner sucks). I've been using both since January 2012.

Changing the workspace from local to server seemed to do the trick with corruption of the cache/workspace, at least.

I'm thinking Sync had something to do with it. Thanks again.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Rooster Brooster posted:

I liked Autofac when I used it. I've also been meaning to check out the one included in Catel.

Just seconding this. We're using Autofac here and it works well.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal
Just a quick .NET/C# obfuscation question: we're (the company I work for) offering a licensing system for a popular .net system. Basically we'll be offering plugin creators of this system a centralized place to sell their plugins, while taking care of all the stuff that developers don't really want to deal with, like keeping a server up and running, and attracting (more) customers.

So I wrote some code in a DRM library that checks local values such as the host domain and license key against our licensing server to return a value with the status of the license (authorized, in trial, etc). Basically the only sensitive value stored on the client server is an obfuscated date (MD5 hashed date with a couple seeds). We use this date to determine whether we need to authorize again (we auth once a day). Because the seeds are stored client side as well, and would be in memory even if they weren't, we've been wondering whether an obfuscation solution would be worth it.

So to get to the point, I'm wondering if we obfuscate our DRM class library (DLL) with Eazfuscator, whether plugin authors still be able to call the functions by name? If not with Eazfuscator, does anyone have an obfuscation solution that will keep function names the same, and simply obfuscate everything else? Also, according to general consensus would obfuscation be worthwhile in the sort system we've made?

Thanks.

Knyteguy fucked around with this message at 07:55 on Aug 6, 2013

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

crashdome posted:

I've purchased Eazfuscator in the past and although I really only used it once (and not for a public class library), I seem to remember being able to control whether or not certain public class and method names were obfuscated. I haven't used it in years though. Is there a trial?

As far as worthwhile? I can't say. It makes it ugly to look at for sure but, not impossible to figure out.

Thanks for your reply. We're using the free version of Eazfuscator which was available on NuGet. I'll have to dig through the configuration a bit more to see if there is an option for renaming functions.

If anyone else has any information on other free obfuscation software that would be great, too. I checked out most of the ones Stack Overflow mentioned, but most replies were at least a year old.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal
Not a question, but I couldn't find our old licensing thread.

It looks like a GPLv3 (modified) license will be tested in court: http://www.nopcommerce.com/boards/t/24760/smartstore-rejected-to-meet-nopcommerce-license-terms-lets-discuss.aspx

(.NET software)

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal
Is it possible to return a 301/302 redirect view from a controller? Here's the setup:

C# code:
        [HttpPost]
        public ActionResult Configure(ConfigurationModel model)
        {
            // Save the settings   
            _searchRankSettings.SKU = model.sku;
            _searchRankSettings.GTIN = model.gtin;
            _searchRankSettings.Manufacturer = model.manufacturer;
            _searchRankSettings.Manufacturer_map = model.manufacturer_map;
            _searchRankSettings.Product = model.product;
            _searchRankSettings.Product_tags = model.product_tags;
            _searchRankSettings.Short_description = model.short_description;
            _searchRankSettings.Full_description = model.full_description;
            _searchRankSettings.Category_map = model.category_map;

            _settingService.SaveSetting(_searchRankSettings);

            // Update the database with our new values
            UpdateSearchRankRecord("SKU", model.sku);
            UpdateSearchRankRecord("GTIN", model.gtin);
            UpdateSearchRankRecord("MFGR Part Number", model.manufacturer);
            UpdateSearchRankRecord("Product Name", model.product);
            UpdateSearchRankRecord("Manufacturer Map", model.manufacturer_map);
            UpdateSearchRankRecord("Category Map", model.category_map);
            UpdateSearchRankRecord("Short Description", model.short_description);
            UpdateSearchRankRecord("Full Description", model.full_description);
            UpdateSearchRankRecord("Product Tags", model.product_tags);

            // Update/insert into the core record
            UpdateTheCore(model);

            return View("Nop.Plugin.Misc.SearchRank.Views.Settings.configuration", model);
        }
Instead of just returning that view (which is the source of the post as well), I want to 301 redirect into the [HttpGet] method of the same name instead. How can I do this? Thanks.

Knyteguy fucked around with this message at 00:25 on Sep 27, 2013

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

ManoliIsFat posted:

So you have a POST on configure that sets up these various things, and you wanna redirect to a GET on configure...why a get on the same method? Are you gonna have some
code:
if(METHOD=="POST"){do this}else{do that}
to tell what you're doing? Different controller methods? What's the GET version look like?

Actually, I'm trying to figure out exactly what you're doing. You post some config values to this method...why the redirect? Why not just show the view right then and there? Or am I not understanding you, and you're trying to redirect to a totally different controller?

But you could return a new RedirectResult() or yes, RedirectToAction() is probably exactly what you want.

Hey Manoli,

here's the get:
C# code:
        /// <summary>
        /// Configure SearchRank
        /// </summary>
        /// <returns>The configured view</returns>
        public ActionResult Configure()
        {
            nopModifiedCoreFunctions Core = 
                                    new nopModifiedCoreFunctions(_nopModifiedCoreRecord);

            string ProductId = nopModifiedSettings.ProductId;
            int SafeDays = nopModifiedSettings.SafeDays;
            int VendorId = nopModifiedSettings.VendorId;

            //Pull our license key from nopModified
            string currentStoreLicenseKey = Core.GetLicenseKey(ProductId, 
                                                _storeContext.CurrentStore.Url, VendorId);

            // Set the model to be sent to our view based on our setting service values
            var model = new ConfigurationModel();
            model.sku = _searchRankSettings.SKU;
            model.gtin = _searchRankSettings.GTIN;
            model.manufacturer = _searchRankSettings.Manufacturer;
            model.manufacturer_map = _searchRankSettings.Manufacturer_map;
            model.product = _searchRankSettings.Product;
            model.product_tags = _searchRankSettings.Product_tags;
            model.short_description = _searchRankSettings.Short_description;
            model.full_description = _searchRankSettings.Full_description;
            model.category_map = _searchRankSettings.Category_map;
            model.domain = _storeContext.CurrentStore.Url;

            // NopModified - set the license_key and expire_date
            model.license_key =
                string.IsNullOrEmpty(currentStoreLicenseKey) ? "Trial" : currentStoreLicenseKey;

            model.expire_date = Core.GetExpirationDate(ProductId, model.license_key, 
                                    _storeContext.CurrentStore.Url, VendorId, SafeDays);

            return View("Nop.Plugin.Misc.SearchRank.Views.Settings.configuration", model);
        }
Explanation: Our post method gets it's variable information from the model that's posted in our form in the configuration view. We don't actually set the variable expire_date in that form, but instead just set it in the get for display purposes only (as shown in the get).

We also do not have a license_key in our settings service defined because we can have multiple license keys for one product in a multi-domain environment, so it was more important that we actually allow different license keys for multiple domains in this environment (the rest of the settings that we set in these methods are pretty optimized and tested, so they can be shared across domains without any real benefit loss).

So basically because we don't have these variables (expire_date, license_key) in the settings service, we don't send them to the view in the post. I know we could set them the same way we do in the get, but for standards it would be best to allow a user to refresh after posting, without reposting data. Also DRY and such.

Thanks for the help (both of you); I'll give that redirect a try and see what happens.

Also edit: this method really needs refactoring; I just found my morning project.

E2: refactored a bit

Knyteguy fucked around with this message at 17:31 on Sep 27, 2013

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal
Bah RedirectToAction("Configure") didn't work:

quote:

Child actions are not allowed to perform redirect actions.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Child actions are not allowed to perform redirect actions.


Oh well it's deployment day, if anyone has any ideas on how to fix I'll throw it in the next version.

Edit: got it. return Configure(); did the trick.

Knyteguy fucked around with this message at 18:28 on Sep 27, 2013

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal
Does anyone have a good resource on caching in .Net MVC 4? Also perhaps something to help me use the profiler to identify bottlenecks? It can be free or paid (though hopefully free on the profiler).

Thanks!

Edit: In particular, System.Runtime.Caching

Knyteguy fucked around with this message at 23:58 on Nov 12, 2013

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Fastbreak posted:

After digging in to NoSql and Document DBs, we are finally at the point where we are going to use them in some production apps. That means RavenDB is no longer viable since we don't have any budget to pay for it. We are looking into free options and so far RaptorDB and BrightStarDB are looking good. We are starting to flesh them out now, anyone tried them and had some success/ Any other recommendations we should try? Something that can work embedded as well would be needed.

Thanks in advance!

There's a lot of good discussion regarding a few different NoSQL databases here: http://forums.somethingawful.com/showthread.php?threadid=3571035&userid=0&perpage=40&pagenumber=2 (the front end development thread).

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

mintskoal posted:

MiniProfiler by StackExchange is really awesome for MVC 4 profiling.

Can you describe a bit more what you're caching or attempting to do?

Hey thanks a lot this is absolutely perfect.

Basically we have a request table that we now know is looking like this on an initial load:
code:
Class                  Time
-------------------------------
CategoryController.cs  27828ms
AjaxFilters.cs         21053ms
---
Total Load Time        49093ms
And we knew there were some really serious issues somewhere on this page load due to a 50 second request start to request finish, but we didn't know where.

I'm not 100% sure what we need to cache yet, but with the Mini Profiler I'm drilling it down right now. Subsequent page loads are still 10,000ms minimum.

I had tried to use the VS profiler, but this is absolutely awesome.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal
So, here's a logic defying problem I'm running into with C# MVC:
Given this code below:


All of that commented out code works. In fact it assigns filterableSpecificationAttributeOptionIds a List<int> containing the collection { 1, 3, 6, 7 } after everything is said and done. This collection is correct.



In this second image, I have highlighted in blue where I hit the actual problem which is:
If I use the commented code to return the collection ({ 1, 3, 6, 7 }) this method will take about 10 seconds to complete. If I use the code that is currently uncommented in image 1 (simply creating a new list with those collection values) this method goes through extremely quickly.

I have tried debug and release builds. This will happen whether I'm debugging, or not. None of these methods are async. The method that hangs (highlighted image 2) is the last line here:
C# code:
        public virtual void PrepareSpecsFilters(IList<int> alreadyFilteredSpecOptionIds,
                IList<int> filterableSpecificationAttributeOptionIds,
                ISpecificationAttributeService specificationAttributeService, 
                IWebHelper webHelper,
                IWorkContext workContext)
            {
                var allFilters = new List<SpecificationAttributeOptionFilter>();
                if (filterableSpecificationAttributeOptionIds != null)
                    foreach (var saoId in filterableSpecificationAttributeOptionIds)
                    {
                        var sao = specificationAttributeService.GetSpecificationAttributeOptionById(saoId);
The service method that var sao gets is here:
C# code:
        /// <summary>
        /// Gets a specification attribute option
        /// </summary>
        /// <param name="specificationAttributeOptionId">The specification attribute option identifier</param>
        /// <returns>Specification attribute option</returns>
        public virtual SpecificationAttributeOption GetSpecificationAttributeOptionById(int specificationAttributeOptionId)
        {
            if (specificationAttributeOptionId == 0)
                return null;

            return _specificationAttributeOptionRepository.GetById(specificationAttributeOptionId);
        }
Which is just an entity framework implementation.

Does anyone see what the heck might be up? The commented code and the uncommented code in the first image are functionally identical as far as I can tell?

code:
Specs: 
Visual Studio 2012 Update 4
.NET MVC 4
Edit: that orderby in image 1 is superfluous and was only for testing if collection order was causing the problem. There was no perceivable difference before or after.

Knyteguy fucked around with this message at 18:23 on May 14, 2014

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Ithaqua posted:

Did you use a profiler? Use a profiler. There are a ton of moving parts here and no one in this thread is going to be able to pinpoint which moving part is causing the problem by looking at a few snippets of your code.

I can appreciate that. I'm just looking to see if there's any known bugs. Here's what profiling found out for me:

Slow Method:


Fast Method:


Basically exactly the same thing that I'm seeing with the debugger: the SQL calls though identical for some reason take more time when the list is populated from my method instead of declared as a new list with the same exact collection.

Strange but I'm sure I'll figure out what's up.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Ithaqua posted:

Profile the code, not the SQL.

Do you know of a good free profiler that can do better than the picture below? My Google-fu is failing me. I profile the code constantly but this is about the best data I can get with it:


I've tried the JetBrains demo but it had a bit of a learning curve. Almost all of this poor performance is from core NopCommerce (open source ASP.NET store software) which is just absolutely terrible for the amount of data we have (100,000 products). I think it's too late in the game to get the company to switch though.

Step 9 and of course PrepareSpecsFilter is where all of the excess is (the CategoryNavigation sucks too but that's for another day).

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

GrumpyDoctor posted:

I'm really curious about what's causing this - if you figure it out, be sure to post it!

So I'm fairly certain it must be an EF bug or EF threading issue. Building out the data from a stored procedure rather than going through LINQ/EF fixed this. This was regardless of the fact that stepping through the code in the debugger worked very quickly.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Ithaqua posted:

Use SQL Server Data Tools. Import your database into an SSDT project, and then you have a source-controlled, canonical version of your database. Change things in your SSDT project, then publish it when you need to do a release. There you go, source controlled database objects.

For data, make database backups. Don't dump poo poo to Excel, that's dumb.

Dangit, Ithaqua! Every time I want to answer one you beat me to the punch! (just kidding man we're all lucky to get your help).

Just wanted to chime in this is what we use at work and it works perfectly.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

beuges posted:

I'm not sure if this is something straightforward or not. If you're developing a large MVC site, is it possible to break that up into separate projects? I don't mind if the sub-projects get included into the main site at compile time or run time... it's basically to potentially solve two problems in my head (that may not even be problems, or may be solved better in other ways):

1. reuse of code across different sites via a shared library, so you just maintain one set of code
2. easy/standard way of adding functionality to a site via a sort-of plugin type of design, where new functionality can follow some sort of predefined interface or design pattern, and then the resulting DLLs and Views can just be dropped onto the web server (maybe with some updates to the web.config as necessary) without having to add it to the main project, rebuild and redeploy the entire thing.

This sounds like it should be a solved problem, but all my searching hasn't turned up anything useful.

Check out nopCommerce (.net mvc). If you're asking what I think you're asking, then they organize their solution in that manner.

https://nopcommerce.codeplex.com/SourceControl/latest

It's probably easier to download the source and run it from Visual Studio to get a good idea of how they do it, as opposed to that web interface though.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Funking Giblet posted:

I probably wouldn't copy nopCommerce, I mean, have you seen their controllers?

I've used MEF in the past to import controllers and views via a DLL, but there's no reason a standard IOC container couldn't do the same.

I use the mediator pattern to lighten controllers to the point that could essentially be created dynamically and their methods dispatched within an ActionInvoker. The mediator pattern just requires you to know the type of command or query for a given action, and return a result or issue a command. Which library this happens in is up to you. I wouldn't go down this route until I've encountered enough complexity within the app though. If your controllers look like this
https://nopcommerce.codeplex.com/SourceControl/latest#src/Presentation/Nop.Web/Controllers/CatalogController.cs then it's time to consider something better. (Also their dependency graph and start up time for each controller must be horrid!)

Unfortunately yes. I have to work with their controllers nearly daily (it's awful and makes me hate my job sometimes). We have a custom eCommerce package based off their source at work. They do some stuff right and really well though. I still kind of copy their layout tree on personal projects. Maybe I'm just familiar with it though.

I am going to look into this mediator pattern though. I might be able to convince the owner of the company we should spend some time on this. He's a developer so he should understand. Of course he might say "Clients don't care if the code looks pretty. We don't need to spend any time refactoring." and then we'll have to work on it later and not know what the gently caress. I think the last time he said that he also said we shouldn't add the project to source control because we can keep the project on our dropbox. [/rant] (sorry)

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

RICHUNCLEPENNYBAGS posted:

Tremendously useful in eliminating some tedium from unit testing. No reason not to use it.

This thread is over 7 years old and the OP sucks. It would be really cool for someone to create a new OP with stuff like this in it (AutoFixture). Helpful common libraries and VS addons, newbie resources, books, etc.

Adbot
ADBOT LOVES YOU

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

c355n4 posted:

Any suggestions on a good book to learn MVC? Coming from a background in webforms.

Assuming you mean ASP.NET MVC, maybe http://www.amazon.com/Pro-ASP-NET-Experts-Voice-ASP-Net/dp/1430265299/ref=sr_1_1?s=books&ie=UTF8&qid=1403031126&sr=1-1 ? I've used version 4 of this book as a reference and it's pretty solid. If you're not familiar with the MVC pattern it explains it, and at least in version 4 a good portion of the beginning of the book is building a multifaceted web project using MVC. YMMV of course.

  • Locked thread