2

Just some background about my application. I am developing an ASP.Net MVC 3 Web App which uses Entity Framework 4.1 for data persistence. My application is tiered in that it has a UI layer, Service layer, Repository layer etc. I also use Unity for my Inversion of Control Container.

When a user registers on my application, I create two random codes (Email and Mobile verification codes) using the StringBuilder. I then assign these two random codes to their appropriate properties in a User Object, see below.

User validateUser = new User();

validateUser.firstName = model.firstName.Trim();
validateUser.lastName = model.lastName.Trim();
validateUser.email = model.Email.Trim();

//Create Email and Mobile Verification Codes
string randomEmailCode = "";
randomEmailCode = _notifyService.GenerateEmailCode();
validateUser.emailVerificationCode = randomEmailCode;

string randomMobileCode = "";
randomMobileCode = _notifyService.GenerateMobileCode();
validateUser.mobileVerificationCode = randomMobileCode;

NotifyService

public string GenerateEmailCode()
{
    StringBuilder builder = new StringBuilder();

    builder.Append(RandomString(4, true));
    builder.Append(RandomNumber(1000, 9999));
    builder.Append(RandomString(2, false));
    return builder.ToString();
}

public string GenerateMobileCode()
{
    StringBuilder builder = new StringBuilder();

    builder.Append(RandomString(3, true));
    builder.Append(RandomNumber(1000, 9999));
    builder.Append(RandomString(2, false));
    return builder.ToString();
}

private int RandomNumber(int min, int max)
{
    Random random = new Random();
    return random.Next(min, max);
}

private string RandomString(int size, bool lowerCase)
{
    StringBuilder builder = new StringBuilder();
    Random random = new Random();
    char ch;
    for (int i = 0; i < size; i++)
        {
            ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
            builder.Append(ch);
        }
        if (lowerCase)
            return builder.ToString().ToLower();
        return builder.ToString();
    }

I then add the user to my DBcontext and call the SaveChanges() method to save the new User into my database.

_accountService.AddUser(validateUser);
_accountService.Save();

Now, when I go into my database and find the new User which has been added, the emailVerificationCode and the mobileVerificationCode are both the same. However, if I put a break point on my code at the following line

randomEmailCode = _notifyService.GenerateEmailCode();

And trace through until the Save, and then go check the database for the new User, both emailVerificationCode and the mobileVerificationCode codes are different, as expected.

I cannot understand why when I run the application it inserts the same code for both properties.

Can anyone please help with this?

Thanks.

UPDATE

I did as Jane suggested, ie, put in hard coded values for each property like so

validateUser.emailVerificationCode = "emailCode";
validateUser.mobileVerificationCode = "mobileCode";

Ran the application again, and this time the two hardcoded values were inserted as expected. Does this mean that that my two methods GenerateEmailCode() and GenerateMobileCode() are not working correctly?

tcode
  • 5,055
  • 19
  • 65
  • 124
  • so the 2 codes are only different when you're debugging ? – Thousand Sep 25 '12 at 09:56
  • @JaneDoe Yes Jane, only different when I debug. – tcode Sep 25 '12 at 09:59
  • and when you run it, which code is duplicated? the mobile or email code? – Thousand Sep 25 '12 at 10:00
  • @JaneDoe It's tough to know which code is duplicated Jane when I run the application, I can only see the codes that are generated when I debug. However, I have a feeling it's the mobileVerificationCode which is duplicated. – tcode Sep 25 '12 at 10:02
  • 1
    hmm ok thats weird tho. Are you sure the problem isn't located somewhere else? Because this seems to be just fine.. Can you try this: just put a hardcoded value for email like "emailCode" and a hardcoded value for mobile like "Mobile" ? See if that duplicates one of them when you just run it. If that goes ok then it must be something with the generation methods – Thousand Sep 25 '12 at 10:04
  • @JaneDoe Very weird indeed. I can't see anywhere else in my code which could be causing this. It is so strange that it doesn't happen when I debug though. – tcode Sep 25 '12 at 10:07
  • 2
    Simple question - how are your random numbers/strings generated? If it based on any time, then it would explain why it is different in debug, and the same without debugging. Can you add the code for the Random... methods? – Maarten Sep 25 '12 at 10:18
  • 2
    How are you generating those random codes? My guess: you initialize a new Random class. But that will use the time as seed and when you run it, the time will be the same, so the "random" output will be the same also. When debugging, you introduce a delay, thus different values. – Hans Kesting Sep 25 '12 at 10:19
  • Maarten and HansKesting I have already showed how I generate the random codes in my question above, under the heading NotifyService. But I believe you are both on the correct path with your suggestions. – tcode Sep 25 '12 at 10:25
  • Unless I'm missing something, I do not see the implementation of the RandomString(int, bool) or RandomNumber(int,int) which is necessary to see **how** you are generation the random numbers. How you use the random numbers/strings to come to a 'generated code' is clear. – Maarten Sep 25 '12 at 10:29
  • @Maarten Apologises, I have now updated question. – tcode Sep 25 '12 at 10:34
  • 1
    @tgriffiths - as we suspected, you are using `new Random()`, which is causing the problems. See previous comments by me and Maarten and the answer by Jane Doe. – Hans Kesting Sep 25 '12 at 10:35
  • just a thought. why not using System.Guid.NewGuid() ? – itsho Sep 25 '12 at 10:41
  • @itsho that is a possibility, but now that I have this working I'll stick with it. Thanks though. – tcode Sep 25 '12 at 10:47

1 Answers1

3

there is probably something wrong with the way you are generating those random codes. As others have pointed out, the problem is most likely that you are creating instances of the random class too close in time.

try to declare a static random generator:

static Random r = new Random();

then use the static random to generate the code: (in what way you generate the code is up to you obviously but something like this should give you an idea):

 public static string generateCode()
        {          
            string chrs = "abcdefghijklmnopqrstuvwxyz";
            char[] arr = chrs.ToCharArray();
            string code = "";
            for (int i = 0; i < 5; i++)
            {
                code += arr[r.Next(arr.Count())];
            }
            return code;
        }

when i run this:

 var firstCode  = generateCode();
 var secondCode = generateCode();

i get 2 different values.

here's another helpful link

Community
  • 1
  • 1
Thousand
  • 6,562
  • 3
  • 38
  • 46