2

Hi i'm new to MVC and EF so this may be a really simple question but what is the best way to prevent the user from trying to enter duplicate records?

I have a simple look up table with one column which is the primary key. I'm creating a maintenance screen so admins can add extra items to the look up list. My controller looks like :

public ActionResult Index(string NewRow)
    {
        try
        {
            CaseType t = new CaseType { ID = NewRow };
            if (ModelState.IsValid)
            {
                UOW.CaseTypes.Add(t);
                UOW.Save();
            }
        }
        catch (Exception ex)
        {
            ModelState.AddModelError("", ex.Message);
        }
        return View(UOW.CaseTypes.All());
    }

Which stops the duplicate records and stops the yellow screen of death but the message displayed is : "An error occurred while updating the entries. See the inner exception for details." which is no good for the users.

I was just wondering if there is a better way to catch the error.

tereško
  • 58,060
  • 25
  • 98
  • 150
Jammy
  • 779
  • 2
  • 13
  • 26

2 Answers2

4

For show validation error I use something like this:

MainEmail it's property from ViewModel

        var mod = ModelState.First(c => c.Key == "MainEmail");  // this
        mod.Value.Errors.Add("Row's shouldn't duplicates.");    // this

        if (ModelState.IsValid)
        {
            return RedirectToAction("Details");
        }

        return View(client);

Error will show's in this field in view:

    <div class="editor-label">
        @Html.LabelFor(model => model.MainEmail)
    </div>

And for future, you must hide your error screen! You need to display a custom error page:

If you use asp-mvc-3, add to web.config such string:

  <system.web>
     <customErrors mode="On" defaultRedirect="~/Error" />
     ...

And users will have /Shared/Error.cshtml page insted of page with exception message (which can show sequrity data).

ADD

About unique constraint creation was discussed here Unique Constraint in Entity Framework Code First

than you can check about records duplication with your try code.

In my application I use code first and don't add unique constraint because it's lead to low testability. In that case use simple Find before saving changes.

First aproach is little bit faster.

Approach two is grow up testability.

Community
  • 1
  • 1
Alexander Molodih
  • 1,928
  • 2
  • 20
  • 30
  • Hmm...my answer not help you? – Alexander Molodih Sep 16 '11 at 19:03
  • excellent thanks, and i was planning on removing the error screen its just in development right now but thanks for the top tip. – Jammy Sep 19 '11 at 12:28
  • Hi, just got around to messing around with this and while your code is helpfull it does not actually achieve what i was looking for. It seems to just look for a field in the form data and add a validation message. I was looking for was a way to check for duplicates, so for example if i already have case type "22" in the table and at some point a user trys to create another "22" the system should say "sorry thats a duplicate" rather then "bam" yellow screen of death. Just wondered if i should run a "find" on the data first or catch the error which is less strain on the server? – Jammy Sep 22 '11 at 13:37
  • If you also add unique constraint to the table column in the server, be better if you catch exception (It's more faster). – Alexander Molodih Sep 22 '11 at 13:46
0

If you want to get the inner exception you can do like this,

catch (Exception ex)
        {
           while(ex.InnerException!=null){
                 ex=ex.InnerException;
           }
            ModelState.AddModelError("", ex.Message);
        }

no too sure about the syntax :)

Jayantha Lal Sirisena
  • 21,216
  • 11
  • 71
  • 92