0

I've done this in webforms but having a hard time trying this in ASP.NET MVC. I'm using the Visual Studio 2017.

I'm trying to create an Entity, and if the entity already exists with the id number, I would like to have an alert something like 'same id exists!' and stay on the same page.

However, if the id does not exist, it will just go on to another page (redirect, I guess) having forms to make another entity which is a detail entity of the first entity.

Right now all I can think of would be having a boolean when the form loads, (on javascript, maybe.. ) because unlike webforms the codebehind is not integrated with the view, and make a boolean true when the same id is inserted, but I just can't get my head around this and there should be a better way of doing this.

I've read about web-api and willing to try the method, but can't think how web-apis will enable me to do this.

    public ActionResult InsertDetail()
    {
        string poN = Request.Form["entityNum"];
        var thisEntty = _context.entityDB.FirstOrDefault(p => p.Entity.Equals(entityNum));

        if (thisEntity != null) // same entity exists!
        {
            ViewBag.Javscript = "<script language='javascript' type='text/javascript'>alert('Data Already Exists');</script>";
            return RedirectToAction("Insert");
        }
    }

This is the code I tried, so I made a form from InsertAction and when calling insertDetail, I'm trying this, but for some reason this doesn't work.

Please tell me if the explanation is vague or unclear.

Thanks

6
  • Are you using Entity Framework? Just query your table with the entity id, and if you get a result return it, if not redirect. Commented Aug 6, 2018 at 20:56
  • @maccettura I am, but I just don't know how to set an alert Commented Aug 6, 2018 at 20:59
  • So do you want to submit the form on Insert view, call the InsertDetail() and stay on Insert view if there is already a detail with the same Id and just show an alert message over Insert view? Commented Aug 6, 2018 at 21:38
  • @Ghukas That is correct. Is that a bad idea? Commented Aug 6, 2018 at 21:42
  • You are redirecting to another view so using ViewBag is pointless (that is for passing data from a controller to a view). If you want to stay on the same page, then add a ModelStateError and return the view. Commented Aug 6, 2018 at 22:27

3 Answers 3

3

Without knowing your setup or your current level understanding of MVC, I can only share a general approach. Coming from Web Forms to MVC requires a paradigmn shift which in the end will make you a better programmer.

First you install Entity Framework in your project through NuGet.

Next, you create a Model which contains every field you require for the entity. In this example, I will call it "Member" with an Id, Name, Email, and Address:

public sealed class Member 
{
   public int Id { get; set; }
   public string Name { get; set; }
   public string Email { get; set; }
   public string Address { get; set; }
}

By making your field of type "int" and naming it "Id" Entity Framework will automatically make that field a PRIMARY KEY and an AUTO NUMBER without you having to configure anything.

Next, you add this entity to the ApplicationDbContext class:

public DbSet<Member> Members { get; set; }

As it's often the case in real projects, your form will only collect SOME of the fields in your entity. In this example I want to collect only Name and Email and leave the address to be filled out by the user later. For that, you create a View Model that will be responsible for collecting just the data you want the user to provide. To keep things nice and organized, I would create a separate folder called "ViewModels" and keep all my view models in there:

public sealed class MemberViewModel 
{
   public int? Id { get; set;}

   [Required]
   public string Name { get; set; }

   [Required]
   [EmailAddress]
   public string Email { get; set; }
}

By making the Id nullable in your view model, you can use the same view model for either creating a new member or updating an existing member.

Also, as a rule of thumb, decorate your view models with Data Annotations for validation purposes.

It is the responsibility of your view models to validate data before passing it to the entity models and NOT the entity models themselves. Why? Separation of concerns: an important practice that is often ignored in Web Forms programming.

Go to your view (which should be named InsertDetail) and at the top of the view add the View Model:

@model ViewModel.MemberViewModel

Now you have created a strongly typed view based on your view model. Although not required, you can now add the fields to your view using HTML helpers like so:

@Html.TextBoxFor(m => m.Email, new { @class = "form-control", autofocus = "", placeholder = "Email" })

You may also decide to add the Id using a hidden field, but if you are using the form just to insert data into the table, it's best to leave the Id field out because this will cause its value to be NULL. However if you decide to add the Id as a hidden field you do it this way:

@Html.HiddenFor(m => m.Id)

To display validation errors at the top of the page, add the following inside your "form" tag or BeginForm HTML helper but before any form fields:

@Html.ValidationSummary("", new { @class = "text-danger" })

To prevent form spoofing from hackers add this line before the validation summary:

@Html.AntiForgeryToken()

Now go to your controller. You don't need to redirect anywhere else to carry out the insertion process. You can handle everything in your controller.

public ActionResult InsertDetail(MemberViewModel model)
        {
            if (ModelState.IsValid)
            {
                // Get context (this should be done through a repository but let's focus)
                using (var ctx = new ApplicationDbContext())
                {
                    var member = new Member();

                    if (model.Id == null)
                    {
                        // Insert Member
                        member.Name = model.Name;
                        member.Email = model.Email;
                        ctx.Members.Add(member);
                    }
                    else
                    {
                        // Check if Id already exists
                        int memberId = 0;
                        bool result = int.TryParse(model.Id.ToString(), out memberId);
                        member = ctx.Members.FirstOrDefault(x => x.Id == memberId);
                        if (member != null) // this member already exists
                        {
                            // You can decide to throw an error or update the entity. Let's throw error
                            ModelState.AddModelError("", "Member Already Exists");
                            return View(model);
                        }
                    }
                }
            }
            // If you get here then there is a validation error
            return View(model);
        }
Sign up to request clarification or add additional context in comments.

Comments

0

You can make use of the inbuilt error handling from the MVC ModelState.

So on the controller you set errors on the model and return the same view:

   public ActionResult InsertDetail()
    {
        string poN = Request.Form["entityNum"];
        var thisEntty = _context.entityDB.FirstOrDefault(p => p.Entity.Equals(entityNum));

        if (thisEntity != null) // same entity exists!
        {
           ModelState.AddModelError("", "Data Already Exists");
           return View("Insert");
        }
    }

On the view markup you can have the js for your custom error handling. In this case you want to do an alert, so the following code only runs if there's errors, grabs them all and displays:

<script type="text/javascript">
    @if (!ViewContext.ViewData.ModelState.IsValid)
{
    var sb = new System.Text.StringBuilder();
    foreach (var modelState in ViewContext.ViewData.ModelState.Values)
    {
        foreach (var error in modelState.Errors)
        {
            sb.Append(error.ErrorMessage);
            sb.Append("\\n");
        }
    }
    @:alert('@sb.ToString()');
}
</script>

Comments

0

Just make sure you are passing primary key is 0 if primary key set as identity and other unique constraint not duplicate.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.