• 0

[C#/ASP.NET] Simple change refuses to work...


Question

So I duplicated a web service that generates pricing for things at our work to add on to the new service for testing before we make any changes. So I made a simple change to this new web service. We have a formula class file. I made one change:

Formula.cs:

public Formula()
		{
		}

		public Formula(int material)
		{
			switch (material)
			{
				case 0:
					this.V26 = 50;
					break;

				case 1:
					this.V26 = 30;
					break;

				default: this.V26 = 50; break;
			}
		}

I added the option to leave out a material id b/c the old code uses one material so I want backwards compatibility.

This is the code I wrote into the web service, which before, just didn't have the integer in it.

WebService.amsx.cs

public static void _Quote(int dbQuoteId, int[] quantity, double resinType, double layerThickness, int gl_material, out double quoteAmount)
		{
			Formula quote = new Formula(1);

It still calls the first function of the Formula class. It refuses to call the second method I wrote. Why? I mean logic should FORCE it to at this point. I am telling it to use the second method, however it uses the first...

Link to comment
Share on other sites

16 answers to this question

Recommended Posts

  • 0

what?! lol ;)

i think i get what you mean... but i'm doing a bit of guess work. I think you mean it uses the first case option.. which would be correct..

when you step through the code (as i am assuming you are doing) it will stop on the case 0: line, go ok, it's not 0.. then skip to the case 1: line and then enter that option because the case is 1

unless i'm a bit off the mark here? it is fairly late

i'll pop back in the morning when i've had my coffee, and you've had time to reply :)

Link to comment
Share on other sites

  • 0

thanks for the reply! but no you are a little off, I mean. Like when you call a contructor if you specify a set of parameters it has to match the proper construct in the class to call it. So Formula() would go to the construct Formula(no parameters). Formula(1) 1 being an int, has to go to Formula(int material) { }. But it's ignoring my int parameter and using the Formula() {} section. When by law it should go to Formula(int material). So the web service calls the contructor with an int parameter:

public static void _Quote(int dbQuoteId, int[] quantity, double resinType, double layerThickness, int gl_material, out double quoteAmount)
		{

			Formula quote = new Formula(1); // Contructor with an int.

And I did testing and it's going to code:

public Formula()
		{
			//this.V26 = 50;
		}

Instead of the second construct:

public Formula()
		{
			//this.V26 = 50;
		}

		public void UpdateCode()
		{
			this.V26 = 80;
		}

		public Formula(int material) ///////////////////////// SECOND CONSTRUCT THAT NEVER GETS CALLED FOR SOME REASON :(
		{
			switch (material)
			{
				case 0:
					this.V26 = 50;
					break;

				case 1:
					this.V26 = 30;
					break;

				default: this.V26 = 50; break;
			}
		}

Which makes no sense what so ever. I'm FORCING it to make that second method. but it goes to the first method instead. The whole point of this is to pass on to the web service which material is being quoted. Then it makes the variables change accordingly. But I need it to call that second construct first :(

Link to comment
Share on other sites

  • 0

I put your formula class into an application, created a Formula object with the parameter set to integer 1, and it correctly set the V26 property to 30 by stepping through the switch statement in the second constructor. So I'm not sure why you're having a problem. How do you know it's going to the blank constructor? You can't set a breakpoint there because there's no executable code. Are you SURE the second constructor isn't being called (have you set a break point in the "case 1" section to see if it is reached)?

It might be helpful to see your entire Formula class, since the value might be getting set somewhere else.

Link to comment
Share on other sites

  • 0

here's the weird thing. I scraped the original idea. I made a static variable Material (int) in the formula class. public static int Material = 0;

now it's weird b/c it won't let me reset the Material value and give me a new value. It just stays on $126.00. I have to literally set the value right when the construct hits or it won't let me change. So I can set V26 to 30 or 80 they'll generate the right values. Then I try to make it change again and it stays at $126.00...

Formula.Material = 80;
			Formula quote = new Formula();

It won't take the first argument. It ignores it. I could set 5000 or 50 or 100 for the first argument. Comes up as $126.00. Now if I set the same argument into the formula class:

public static int Material = 0;

		/// <summary>
		/// This is the default formula setup. Put in place to avoid previous conflicts
		/// with other web service setups. At the time of first release this was a set of variables
		/// that didn't have the direct on-the-fly ability to change. This was added to add more materials
		/// to the possible list without creating a whole other web service (so sla will have it's own
		/// set of variables as will 3DP, SLS, etc).
		/// </summary>
		public Formula()
		{
			if (Formula.Material != 0)
			{
				this.V26 = 80;
			}
			/*
			switch (Formula.Material)
			{
				case 0:
					this.V26 = 50;
					break;

				case 1:
					this.V26 = 30;
					break;

				default: this.V26 = 50; break;
			}*/
		}

So it will never change from 0. Why? IF I could get that value to change to one it'd work. It won't take it though.

Link to comment
Share on other sites

  • 0

Well, a few things. First, that's overkill for your problem and still doesn't address whatever other problem was wrong with your class in the first place. If there's a problem in your code, you should understand the problem, not run away from it. Second, you need to read up a little bit on static fields. Third, you didn't answer any of the questions from my previous post; those questions were designed to help tease out the problem you're having. Finally, you're using a fair amount of incorrect terminology. I suggest reading a basic C# programming book or even taking some classes to become more familiar with what's what.

The following code works perfectly for me:

	public class Formula
	{
		public int V26 { get; set; }

		public Formula()
		{
		}

		public Formula(int material)
		{
			switch (material)
			{
				case 0:
					V26 = 50;
					break;

				case 1:
					V26 = 30;
					break;

				default: 
					V26 = 50; 
					break;
			}
		}
	}

	public class Application
	{
		static void Main()
		{
			Formula quote = new Formula(1);
			//quote.V26 is set to 30;
		}
	}

Edited by boogerjones
Link to comment
Share on other sites

  • 0

I actually had that code exactly at one point. And sorry for the mix up I was just trying everything b/c I just don't get why it doesn't work. I mean, it blatantly refuses to calculate any other code after the constructor. Like in the constructor I can say this.V26 = 80; The calculated code will come out great. But if I try to say quote.V26 = 100 or 50 or w/e. It just spits out the same code. And yes I kind of self-taught myself C# so I don't know everything about it. I know how to work my way around things for the most part but this is making me scratch my head. The equation is just based on variables. It should be dynamic, not static once it's created. Here's the entire formula.cs file, maybe you can tell me why it refuses to change the equation. B/c after all the web service just gets called by ajax to get a number based on the formula values.

Formula.cs:

using System.Runtime.InteropServices;
namespace TriCom.Bastech.Quote
{
	[ComVisible(true)]
	public partial class Formula
	{
		public Parts Parts = new Parts();
		public double LayerThickness = 6;
		public double R52 = 0.3;
		public double V29 = 60;
		public double ResinType = 2;
		public double U8 = 40;
		public double V8 = 30;
		public double U9 = 25;
		public double V9 = 45;
		public double U13 = 1;
		public double V13 = 2;
		public double U14 = 0 /* TODO: Why is this blank? */;
		public double U15 = 8;
		public double U16 = 9;
		public double V14 = 0 /* TODO: Why is this blank? */;
		public double V15 = 10.1;
		public double V16 = 11;
		public double V27 = 15;
		public double V30 = 5.2;
		public double V31 = 5.85;
		public double R42 = 0.4;
		public double V28 = 45;
		public double R44 = 0.25;
		public double V32 = 10;
		public double V33 = 30;
		public static int Material = 0;

		/// <summary>
		/// This is the default formula setup. Put in place to avoid previous conflicts
		/// with other web service setups. At the time of first release this was a set of variables
		/// that didn't have the direct on-the-fly ability to change. This was added to add more materials
		/// to the possible list without creating a whole other web service (so sla will have it's own
		/// set of variables as will 3DP, SLS, etc).
		/// </summary>

		public int V26 { get; set; }

		public Formula()
		{
			this.V26 = 50;
			if (Formula.Material != 0)
			{
				this.V26 = 80;
			}
			/*
			switch (Formula.Material)
			{
				case 0:
					this.V26 = 50;
					break;

				case 1:
					this.V26 = 30;
					break;

				default: this.V26 = 50; break;
			}*/
		}

		public Formula(int material)
		{
			switch (material)
			{
				case 0:
					V26 = 50;
					break;

				case 1:
					V26 = 30;
					break;

				default:
					V26 = 50;
					break;
			}
		}

		public void UpdateCode()
		{
			this.V26 = 80;
		}

		public double CalculatedLayerThickness4Factor { get { return ((LayerThickness == 4) ? 0.004 : 0.006); } }
		public double D23 { get { return Funcs.SUM(Parts.D); } }
		public double G23 { get { return Funcs.MAX(Parts.G); } }
		public double L23 { get { return Funcs.SUM(Parts.L); } }
		public double L24 { get { return Funcs.SUM(Parts.N); } }
		public double L25 { get { return Funcs.SUM(Parts.M); } }
		public double L26 { get { return Funcs.SUM(Parts.K); } }
		public double Total { get { return Funcs.ROUNDUP((((R52 + (D23 * 0.1)) * (((CalculatedStage2Percent + CalculatedStage3Percent) / 100) + 1)) * V29) + (((((CalculatedStage2Percent + CalculatedStage3Percent) / 100) + 1) * ((Funcs.SUM((((0.4 / CalculatedLayerThickness4Factor) * (((ResinType == 1) ? U8 : V8))) / 60), (((G23 / CalculatedLayerThickness4Factor) * (((ResinType == 1) ? U9 : V9))) / 60), (((((((ResinType == 1) ? U13 : V13)) / 4) * (1 / CalculatedLayerThickness4Factor)) * L23) / 60), (((((((ResinType == 1) ? (((LayerThickness == 2) ? U14 : ((LayerThickness == 4) ? U15 : U16))) : (((LayerThickness == 2) ? V14 : ((LayerThickness == 4) ? V15 : V16))))) / 4) * (1 / CalculatedLayerThickness4Factor)) * L23) / 60))) / 60)) * (V26 - (((((((G23 < 6) ? 1 : 0)) == 1) ? ((6 - G23) / 6) * (V27 / 2) : 0)) + ((((((L25 < 200) ? 1 : 0)) == 1) ? ((200 - L25) / 200) * (V27 / 2) : 0))))) + ((((((ResinType == 1) ? V30 : V31)) * 1.25) * L23)) + (((R42 + (D23 * 0.1)) * (((CalculatedStage2Percent + CalculatedStage3Percent) / 100) + 1)) * V28) + (((R44 + (D23 * 0.2)) * (((CalculatedStage2Percent + CalculatedStage3Percent) / 100) + 1)) * V28), 0); } }
		public double CalculatedStage2Percent { get { return ((L26 < 200000) ? (((L26 / 200000) * V32)) : V32); } }
		public double CalculatedStage3Percent { get { return ((L24 < 3000) ? (((L24 / 3000) * V33)) : V33); } }
	}

I've even tried using a function to update the code within the class (UpdateCode()) and it didn't work either. It's like set up the variables in the constructor or you're out of luck for some reason. Thanks for your help so far you guys are great my boss has been riding me to get this done lol. So I'm just like crap...what to do...neowin to the rescue :)

EDIT: the web service Formula call is programmed as: Formula quote = new Formula(1);

To answer your question about how I knew the first constuctor code was being called was b/c I set a command this.V26 = 100 in the first constructor only. Then the value went sky rocketing up when I uploaded the changes. With constructor 2 not doing much of anything at that point.

Edited by sathenzar
Link to comment
Share on other sites

  • 0

For example ok here is a perfect reason to believe it never calls the second construct. I put in this construct 2 seconds ago:

public Formula(int material)
		{
			this.V26 = 500;
		   /* switch (material)
			{
				case 0:
					V26 = 50;
					break;

				case 1:
					V26 = 30;
					break;

				default:
					V26 = 50;
					break;
			}*/
		}

Still comes out to 123.00 that is always has throughout the whole process. If I set that same code in contruct 1 (no parameters) it makes the value change.

Link to comment
Share on other sites

  • 0

Put

				System.Diagnostics.Debug.WriteLine("Blank constructor called.");

in the default constructor and set a breakpoint on it in the IDE. You have to make sure it really is calling it.

You posted a partial class without its friend classes like Parts. Are you sure there are no other constructors, static or otherwise, in the rest of the class? Also, where and when are you setting the static Formula.Material field?

(The "Total" property is a mess too. :) It should be a function called "CalculateTotal()" rather than a property since it's an involved process not just a simple variable check.)

Link to comment
Share on other sites

  • 0

Hi GreyWoldSC :) I did what you said. it is calling the blank constructor.

As for the partial class question here is Parts, you can see it doesn't really effect anything with the formula constructor.

Parts.cs:

public class Parts
	{
		private List<Part> _parts = new List<Part>();

		public double[] D { get { return array<double>(delegate(Part p) { return p.D; }); } }
		public double[] E { get { return array<double>(delegate(Part p) { return p.E; }); } }
		public double[] F { get { return array<double>(delegate(Part p) { return p.F; }); } }
		public double[] G { get { return array<double>(delegate(Part p) { return p.G; }); } }
		public double[] H { get { return array<double>(delegate(Part p) { return p.H; }); } }
		public double[] I { get { return array<double>(delegate(Part p) { return p.I; }); } }
		public double[] J { get { return array<double>(delegate(Part p) { return p.J; }); } }
		public double[] K { get { return array<double>(delegate(Part p) { return p.K; }); } }
		public double[] L { get { return array<double>(delegate(Part p) { return p.L; }); } }
		public double[] M { get { return array<double>(delegate(Part p) { return p.M; }); } }
		public double[] N { get { return array<double>(delegate(Part p) { return p.N; }); } }

		public void Add(Part p) { _parts.Add(p); }

		private delegate T getter<T>(Part p);
		private T[] array<T>(getter<T> g)
		{
			int len = _parts.Count;
			T[] r = new T[len];
			for (int i = 0; i < len; i++) r[i] = g(_parts[i]);
			return r;
		}
	}

The total property is what the other programmers my company hired to make made. I have no way of contacting them or I'd of asked them what the heck I need to do lol. It's just odd b/c it is to my understanding the web service HAS to execute my Formula(int) function when I specify it, no questions asked. So how can it be calling the blank constructor? That's just illegal to programming logic (to my understanding). The static field I set like this:

Formula.Material = 80;
			Formula quote = new Formula(1);

Link to comment
Share on other sites

  • 0

Web services require a default constructor because of the way they serialize information. You should be able to fix your class by just passing the formula ID to whichever function calculates the information you're needing.

Example:

		public double CalculateTotal(int material)
		{
			switch (material)
			{
				case 0:
					V26 = 50;
					break;

				case 1:
					V26 = 30;
					break;

				default:
					V26 = 50;
					break;
			}

			return Total;
		}

Link to comment
Share on other sites

  • 0
There is obviously another partial class "Formula" that is setting the V26 property. We need to see BOTH Formula partial classes.

The problem is that it's a web service class. XmlSerialization requires a default constructor and it always gets called. Moving the initialization value to a method should fix it.

Link to comment
Share on other sites

  • 0

Added your method and changed the web service constructor to this:

public static void _Quote(int dbQuoteId, int[] quantity, double resinType, double layerThickness, int gl_material, out double quoteAmount)
		{
			/*StreamWriter sw = new StreamWriter("test.txt");
			sw.WriteLine("gl_material = " + gl_material);
			sw.WriteLine("TimeStamp: " + DateTime.Now.ToString());
			sw.Close();*/

			Formula quote = new Formula(1);
			//quote.UpdateCode();
			quote.ResinType = resinType;
			quote.LayerThickness = layerThickness;
			SqlCommand cmd = QuotesRecord.CreateCommand("SELECT * FROM files WHERE quotes_ID = @P0", dbQuoteId);
			SqlDataReader reader = cmd.ExecuteReader();
			int q = 0;
			while (reader.Read())
			{
				Part p = new Part(
					quantity[q++],
					Convert.ToDouble(reader["files_extent_x"]),
					Convert.ToDouble(reader["files_extent_y"]),
					Convert.ToDouble(reader["files_extent_z"]),
					Convert.ToDouble(reader["files_volume"]),
					Convert.ToDouble(reader["files_surface"]),
					(double)Convert.ToInt32(reader["files_triangles"])
					);
				quote.Parts.Add(p);
			}
			quoteAmount = quote.CalculateTotal(1); // this should make the value less then 123.00
		}

Still comes out at 123.00. For the other part of the formula class I will look. But I agree with GreyWolfSC here that the method should change the values anyway since it's just one big long equation. Unless another part of the class is keeping the value static which is beyond me. I'll look for the other part of the class and post it. Unless I executed the previous code wrong you just wrote greywolfsc. But that was pretty straight forward to me I think it should've worked with what you wrote. Here's another curve ball. I even went into the formula file and changed the CalculateTotal(int) to just set V26 to 30. Still comes out 123.00...I guess I should look for the other part of the class? I really do appreciate the help guys thanks for you patience.

EDIT: Found the other partial class:

public partial class Formula
	{
		public Part AddPart(int quantity, string path)
		{
			Part p = new Part(quantity, Mesh.Load(path));
			Parts.Add(p);
			return p;
		}
	}

Link to comment
Share on other sites

  • 0

I'm wanting to pull my hair out over this web service. I've never been so stressed out over something. This thing is like a service from satan lol. It's a joke. ok so I just say you know what, just for laughs, lets change the web service code to this:

public static void _Quote(int dbQuoteId, int[] quantity, double resinType, double layerThickness, int gl_material, out double quoteAmount)
		{
			/*StreamWriter sw = new StreamWriter("test.txt");
			sw.WriteLine("gl_material = " + gl_material);
			sw.WriteLine("TimeStamp: " + DateTime.Now.ToString());
			sw.Close();*/

			TriCom.Bastech.Quote.Formula quote = new TriCom.Bastech.Quote.Formula();
			//quote.UpdateCode();
			quote.ResinType = resinType;
			quote.LayerThickness = layerThickness;

			SqlCommand cmd = QuotesRecord.CreateCommand("SELECT * FROM files WHERE quotes_ID = @P0", dbQuoteId);
			SqlDataReader reader = cmd.ExecuteReader();
			int q = 0;
			while (reader.Read())
			{
				Part p = new Part(
					quantity[q++],
					Convert.ToDouble(reader["files_extent_x"]),
					Convert.ToDouble(reader["files_extent_y"]),
					Convert.ToDouble(reader["files_extent_z"]),
					Convert.ToDouble(reader["files_volume"]),
					Convert.ToDouble(reader["files_surface"]),
					(double)Convert.ToInt32(reader["files_triangles"])
					);
				quote.Parts.Add(p);
			}
			quoteAmount = 16000;
		}

quoteAmount = 16000 and the freaking service returns 123.00 ROFL!!!! I give up, it's like something possessed this thing to make it say $123.00 no matter what. If anyone has any other ideas I'd appreciate it. Seems like a lost cause at this point.

Link to comment
Share on other sites

  • 0
I'm wanting to pull my hair out over this web service. I've never been so stressed out over something. This thing is like a service from satan lol. It's a joke. ok so I just say you know what, just for laughs, lets change the web service code to this:

public static void _Quote(int dbQuoteId, int[] quantity, double resinType, double layerThickness, int gl_material, out double quoteAmount)
		 {
			 /*StreamWriter sw = new StreamWriter("test.txt");
			 sw.WriteLine("gl_material = " + gl_material);
			 sw.WriteLine("TimeStamp: " + DateTime.Now.ToString());
			 sw.Close();*/

			 TriCom.Bastech.Quote.Formula quote = new TriCom.Bastech.Quote.Formula();
			 //quote.UpdateCode();
			 quote.ResinType = resinType;
			 quote.LayerThickness = layerThickness;

			 SqlCommand cmd = QuotesRecord.CreateCommand("SELECT * FROM files WHERE quotes_ID = @P0", dbQuoteId);
			 SqlDataReader reader = cmd.ExecuteReader();
			 int q = 0;
			 while (reader.Read())
			 {
				 Part p = new Part(
					 quantity[q++],
					 Convert.ToDouble(reader["files_extent_x"]),
					 Convert.ToDouble(reader["files_extent_y"]),
					 Convert.ToDouble(reader["files_extent_z"]),
					 Convert.ToDouble(reader["files_volume"]),
					 Convert.ToDouble(reader["files_surface"]),
					 (double)Convert.ToInt32(reader["files_triangles"])
					 );
				 quote.Parts.Add(p);
			 }
			 quoteAmount = 16000;
		 }

quoteAmount = 16000 and the freaking service returns 123.00 ROFL!!!! I give up, it's like something possessed this thing to make it say $123.00 no matter what. If anyone has any other ideas I'd appreciate it. Seems like a lost cause at this point.

You're forgetting we added a CalculateTotal() function. Assuming the gl_material parameter is the same material as the one the Formula class is calculating, you would want to change the end of the function from

quoteAmount = 16000;

to

quoteAmount = quote.CalculateTotal(gl_material);

and it should be at least call the calculation function. :)

Link to comment
Share on other sites

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.