10

I have a form that it has some field and has relationship with database. I'm using entity framework I wanna handle exception before sql server send error message. For example when user enter string value in number field win or web application handle exception before sql server handle it. I wrote this code but it don't work for all the exception. For example if field was empty or has invalid type said input string is not in correct format.

 using (var context  = new entityTestEntities2())
        {
            try
            {
                int stNumber = Convert.ToInt32(textBox2.Text);
                var allCustomers = context.setcust(null, stNumber);
            }
            catch(Exception ex)
            {
                if (ex.Message.Contains("correct format"))
                { 
                int x= System.Runtime.InteropServices.Marshal.GetExceptionCode();
                     MessageBox.Show("error number"+x.ToString()+ex.Message);
                }
             }
        } 
OneFineDay
  • 9,004
  • 3
  • 26
  • 37
heavy
  • 439
  • 2
  • 5
  • 13
  • I recommend `Integer.TryParse` for input from textboxes. – OneFineDay Nov 16 '13 at 05:23
  • my question is general its only an example (int or empty field) – heavy Nov 16 '13 at 05:36
  • 1
    What does the UI look like? We're using MVC3 a lot lately, we'll build out datamodels with attributes and/or use the unobtrusive javascript validation. I'd think you'd want to do validation closer to the UI instead of letting it make a call to the database, especially in a web environment. – Jake Hargus Nov 16 '13 at 05:59
  • i do it with java script in web app but i want to produce core and place exception handle in core.i wanna find a solution for it – heavy Nov 16 '13 at 06:08
  • Validation in EF: http://msdn.microsoft.com/en-gb/data/gg193959.aspx MVC uses Data Annotations on Entities to support jQuery unobtrusive validation http://stackoverflow.com/questions/11534910/what-is-jquery-unobtrusive-validation – Colin Nov 18 '13 at 10:22

3 Answers3

14

You should do validation on the UI first then handle specific errors related to Entity Framework.

Create a Model and use data annotations :

using System.ComponentModel.DataAnnotations;
public class YourViewModel
    {
        [Required]
        [Range(0, 15, ErrorMessage = "Can only be between 0 .. 15")]
        public int stNumber { get; set; }
    }

In your controller return the model to the view:

var model = new YourViewModel();
return View(model);

Bind your textbox to the model by adding the model to your view and using some tag helpers:

@using YourProject.WebUI.Models
@model YourViewModel  

@Html.TextBoxFor(m => m.stNumber )
@Html.ValidationMessageFor(m => m.stNumber )

Now when someone tries to enter a non numeric or a number that is out of range an error will be displayed to the user before bad data is ever sent back to the controller.

To handle Entity Framework exceptions use a try catch:

        try
        {
            var entity = context.yourEntity.FirstOrDefault(o => o.Id == custId);

            if (entity == null) return false;
            entity.value= stNumber;
            entity.ModifiedBy = userId;
            entity.ModifiedDate = DateTime.Now;
            Db.SaveChanges();
            return true;
        }
        catch (DbUpdateException Ex)
        {
            Console.WriteLine(Ex.InnerException.Message);
            return false;
        }

Other Exception types include:

DbUpdateException

An error occurred sending updates to the database.

DbUpdateConcurrencyException

A database command did not affect the expected number of rows. This usually indicates an optimistic concurrency violation; that is, a row has been changed in the database since it was queried.

DbEntityValidationException

The save was aborted because validation of entity property values failed.

NotSupportedException

An attempt was made to use unsupported behavior such as executing multiple asynchronous commands concurrently on the same context instance.

ObjectDisposedException

The context or connection have been disposed.

InvalidOperationException

Some error occurred attempting to process entities in the context either before or after sending commands to the database.

Husam Ebish
  • 4,893
  • 2
  • 22
  • 38
LazyDog
  • 317
  • 4
  • 5
4

Instead of catching Exception you should catch SqlException.

SqlException has a number property that you can use:

catch (SqlException e)
{
   MessageBox.Show("Error number: "+e.Number + " - " + e.Message);
}
Shiraz Bhaiji
  • 64,065
  • 34
  • 143
  • 252
4

What you should do is finding a architecture which is fits your solution model. In general I would do validation before creating the context. If you need more validation in your application you may want to create a validation layer for this purpose.

public class RuleViolation
{
    public string Property {get; set;}
    public string Message {get; set;}
}

public class Program
{
    public static List<RuleViolation> GetRuleViolations(string[] parameters)
    {
        List<RuleViolation> validations = new List<RuleViolation>();

        if(!int.TryParse(parameters[0], out new Int32()))
        {
            validations.Add(new RuleViolation{Message ="Input1 must be integer.", Property = "input1"});
        }
        //more validation

        return validations;
    }

    public static void Main(string[] parameters)
    {
        var validations = GetRuleViolations(parameters);

        if(validations.Any())
        {
            validations.ForEach(x=> Console.WriteLine(x.Message));
            return;
        }

        int input1 = int.Parse(parameters[0]);

        //after all your business logic are ok, then you can go to persistence layer to hit the database.
        using (var context  = new entityTestEntities2())
        {
            try
            {
                var allCustomers = context.setcust(null, input1);
            }
            catch(SqlException exc)
            {
                //here you might still get some exceptions but not about validation.

                ExceptionManager.Log(exc);

                //sometimes you may want to throw the exception to upper layers for handle it better over there!
                throw;
            }
        }
    }
}

Hope the example make more clearer the architecture about validation logic.

Yusuf Uzun
  • 1,491
  • 1
  • 13
  • 32