2017-09-26 113 views
1

我很新ASP.NET Core MVC。我正在使用ASP.NET Core 2.0,C#,EntityFrameworkCore Code First和SQL Server 2016.我设法让我的CRUD操作根据需要工作。ASP.NET Core 2.0防止重复条目

但是,我需要帮助,防止用户在我的表单上多次注册。如果可能的话,我想检查/防止在控制器端的代码内而不是在数据库内的重复条目。

我附上我的代码,如果有人可以协助,我现在有。先谢谢你!

模型

public class Employee 
{ 
    public int EmployeeID { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    public int DepartmentID { get; set; } 
    public Department Department { get; set; } 

    public int AppointmentID { get; set; } 
    public Appointment Appointment { get; set; } 
} 

public class Department 
{ 
    public int DepartmentID { get; set; } 
    public string Name { get; set; } 

    public ICollection<Employee> Employees { get; set; } 
} 

public class Appointment 
{ 
    public int AppointmentID { get; set; } 
    public string TimeSlot { get; set; } 

    public ICollection<Employee> Employees { get; set; } 
} 

的ViewModels

public class EmployeeFormVM 
{ 
    public int EmployeeID { get; set; } 

    [Required(ErrorMessage = "Please enter your First Name")] 
    [Display(Name = "First Name")] 
    [StringLength(50)] 
    public string FirstName { get; set; } 

    [Required(ErrorMessage = "Please enter your Last Name")] 
    [Display(Name = "Last Name")] 
    [StringLength(50)] 
    public string LastName { get; set; } 

    [Required(ErrorMessage = "Please select your Department")] 
    [Display(Name = "Department")] 
    public int DepartmentID { get; set; } 

    public IEnumerable<Department> Departments { get; set; } 

    [Required(ErrorMessage = "Please select your Appointment")] 
    [Display(Name = "Appointment")] 
    public int AppointmentID { get; set; } 

    public IEnumerable<Appointment> Appointments { get; set; } 
} 

的DbContext

public class WinTenDbContext : DbContext 
{ 
    public WinTenDbContext(DbContextOptions<WinTenDbContext> options) : base(options) 
    { 
    } 

    public DbSet<Employee> Employees { get; set; } 
    public DbSet<Department> Departments { get; set; } 
    public DbSet<Appointment> Appointments { get; set; } 

    protected override void OnModelCreating(ModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Employee>() 
      .HasKey(e => e.EmployeeID); 

     modelBuilder.Entity<Employee>() 
      .Property(e => e.FirstName) 
      .HasColumnType("varchar(50)") 
      .HasMaxLength(50) 
      .IsRequired(); 


     modelBuilder.Entity<Employee>() 
      .Property(e => e.LastName) 
      .HasColumnType("varchar(50)") 
      .HasMaxLength(50) 
      .IsRequired();    

     modelBuilder.Entity<Department>() 
      .HasKey(d => d.DepartmentID); 

     modelBuilder.Entity<Department>() 
      .Property(d => d.Name) 
      .HasColumnType("varchar(50)") 
      .HasMaxLength(50); 

     modelBuilder.Entity<Appointment>() 
      .HasKey(a => a.AppointmentID); 

     modelBuilder.Entity<Appointment>() 
      .Property(a => a.TimeSlot) 
      .HasColumnType("varchar(50)") 
      .HasMaxLength(50); 
    } 
} 

EmployeesController

public class EmployeesController : Controller 
{ 
    private readonly WinTenDbContext _context; 

    public EmployeesController(WinTenDbContext context) 
    { 
     _context = context; 
    } 

    // GET: Employees 
    public async Task<IActionResult> Index() 
    { 
     //return View(await _context.Employees.ToListAsync()); 

     var webAppDbContext = _context.Employees.Include(d => d.Department).Include(a => a.Appointment); 
     return View(await webAppDbContext.ToListAsync()); 
    } 

    // GET: Employees/Details/5 
    public async Task<IActionResult> Details(int? id) 
    { 
     if (id == null) 
     { 
      return NotFound(); 
     } 

     var employee = await _context.Employees 
      .SingleOrDefaultAsync(m => m.EmployeeID == id); 
     if (employee == null) 
     { 
      return NotFound(); 
     } 

     return View(employee); 
    } 

    // GET: Employees/Create 
    public IActionResult Create() 
    { 
     var departments = _context.Departments.ToList(); 
     var appointments = _context.Appointments.ToList(); 

     var viewModel = new EmployeeFormVM 
     { 
      Departments = departments, 
      Appointments = appointments 
     }; 

     return View(viewModel); 
    } 

    // POST: Employees/Create 
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598. 
    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public async Task<IActionResult> Create(EmployeeFormVM employee) 
    { 
     if (ModelState.IsValid) 
     { 
      var emp = new Employee(); 
      { 
       emp.FirstName = employee.FirstName; 
       emp.LastName = employee.LastName; 
       emp.DepartmentID = employee.DepartmentID; 
       emp.AppointmentID = employee.AppointmentID; 
      } 
      _context.Add(emp); 
      await _context.SaveChangesAsync(); 
      return RedirectToAction(nameof(Index)); 
     } 

     else 
     { 
      employee.Departments = _context.Departments.ToList(); 
      employee.Appointments = _context.Appointments.ToList(); 
      return View(employee); 
     } 
    } 

    // GET: Employees/Edit/5 
    public async Task<IActionResult> Edit(int? id) 
    { 
     if (id == null) 
     { 
      return NotFound(); 
     } 

     var employeevm = new EmployeeFormVM(); 
     { 
      Employee employee = await _context.Employees.SingleOrDefaultAsync(m => m.EmployeeID == id); 

      if (employee == null) 
      { 
       return NotFound(); 
      } 

      employeevm.EmployeeID = employee.EmployeeID; 
      employeevm.FirstName = employee.FirstName; 
      employeevm.LastName = employee.LastName; 

      // Retrieve list of Departments 
      var departments = _context.Departments.ToList(); 
      employeevm.Departments = departments; 
      // Set the selected department 
      employeevm.DepartmentID = employee.DepartmentID; 

      // Retrieve list of Appointments 
      var appointments = _context.Appointments.ToList(); 
      employeevm.Appointments = appointments; 
      // Set the selected department 
      employeevm.AppointmentID = employee.AppointmentID; 
     } 
     return View(employeevm); 
    } 

    // POST: Employees/Edit/5 
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598. 
    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public async Task<IActionResult> Edit(EmployeeFormVM vmEdit) 
    { 
     if (ModelState.IsValid) 
     { 
      Employee employee = _context.Employees.SingleOrDefault(e => e.EmployeeID == vmEdit.EmployeeID); 

      if (employee == null) 
      { 
       return NotFound(); 
      } 

      employee.FirstName = vmEdit.FirstName; 
      employee.LastName = vmEdit.LastName; 
      employee.DepartmentID = vmEdit.DepartmentID; 
      employee.AppointmentID = vmEdit.AppointmentID; 

      try 
      { 
       _context.Update(employee); 
       await _context.SaveChangesAsync(); 
      } 
      catch (DbUpdateConcurrencyException) 
      { 
       if (!EmployeeExists(vmEdit.EmployeeID)) 
       { 
        return NotFound(); 
       } 
       else 
       { 
        throw; 
       } 
      } 
      return RedirectToAction(nameof(Index)); 
     } 
     return View(vmEdit); 
    } 

    // GET: Employees/Delete/5 
    public async Task<IActionResult> Delete(int? id) 
    { 
     if (id == null) 
     { 
      return NotFound(); 
     } 

     var employee = await _context.Employees 
      .SingleOrDefaultAsync(m => m.EmployeeID == id); 
     if (employee == null) 
     { 
      return NotFound(); 
     } 

     return View(employee); 
    } 

    // POST: Employees/Delete/5 
    [HttpPost, ActionName("Delete")] 
    [ValidateAntiForgeryToken] 
    public async Task<IActionResult> DeleteConfirmed(int id) 
    { 
     var employee = await _context.Employees.SingleOrDefaultAsync(m => m.EmployeeID == id); 
     _context.Employees.Remove(employee); 
     await _context.SaveChangesAsync(); 
     return RedirectToAction(nameof(Index)); 
    } 

    private bool EmployeeExists(int id) 
    { 
     return _context.Employees.Any(e => e.EmployeeID == id); 
    } 
} 

创建视图

@using (Html.BeginForm("Create", "Employees")) 
    { 
     <div class="form-group"> 
      @Html.LabelFor(e => e.FirstName) 
      @Html.TextBoxFor(e => e.FirstName, new { @class = "form-control" }) 
      @Html.ValidationMessageFor(e => e.FirstName) 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(e => e.LastName) 
      @Html.TextBoxFor(e => e.LastName, new { @class = "form-control" }) 
      @Html.ValidationMessageFor(e => e.LastName) 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(d => d.DepartmentID) 
      @Html.DropDownListFor(d => d.DepartmentID, new SelectList(Model.Departments, "DepartmentID", "Name"), "", new { @class = "form-control" }) 
      @Html.ValidationMessageFor(d => d.DepartmentID) 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(a => a.AppointmentID) 
      @Html.DropDownListFor(a => a.AppointmentID, new SelectList(Model.Appointments, "AppointmentID", "TimeSlot"), "", new { @class = "form-control" }) 
      @Html.ValidationMessageFor(a => a.AppointmentID) 
     </div> 

     <div class="form-group"> 
      <button type="submit" class="btn btn-primary">Submit</button> 
     </div> 
    } 

回答

3

你当然可以检查从代码方面的重复条目,但当然你需要,以实现对数据库运行一个查询这个。从您发布的代码,你已经做EmployeesController.Edit类似的东西:

Employee employee = await _context.Employees.SingleOrDefaultAsync(
    m => m.EmployeeID == id); 

if (employee == null) 
{ 
    return NotFound(); 
} 

你可以采取这种方法和应用的变化以EmployeesController.Create。例如: -

Employee existingEmployee = await _context.Employees.SingleOrDefaultAsync(
    m => m.FirstName == employee.FirstName && m.LastName == employee.LastName); 

if (existingEmployee != null) 
{ 
    // The employee already exists. 
    // Do whatever you need to do - This is just an example. 
    ModelState.AddModelError(string.Empty, "This employee already exists."); 
    employee.Departments = _context.Departments.ToList(); 
    employee.Appointments = _context.Appointments.ToList(); 
    return View(employee); 
} 

// Your existing code for creating a new employee. 

我在SingleOrDefaultAsync使用的表达式仅仅是一个例子:你需要决定根据自己的需求是什么让雇员独特。

要看到我展示的控制器代码添加了错误信息,则需要更新创建视图

@using (Html.BeginForm("Create", "Employees")) 
{ 
    @Html.ValidationSummary(true) 
    ... 
+0

感谢您的回复回来。我是否应该实现您在原始发布的代码中提供的内容?我试图把你提供的内部** [HttpPost]创建if if(ModelState.IsValid)**代码,但当我尝试输入重复的名字和姓氏时出现此错误** ArgumentNullException:值不能为空。 参数名称:这行代码中的** ** @ Html.DropDownListFor(d => d.DepartmentID,new SelectList(Model.Departments,“DepartmentID”,“Name”),“”,new {@class = “form-control”})** – Brian

+0

我编辑了解决您的具体问题的答案。你会想考虑重构这个函数来消除这个增加的重复,但我认为这超出了你的具体问题的范围。 –

+0

谢谢你,工作。但是,我没有看到错误消息**此员工已经存在。**当我尝试输入重复条目时,是否必须在创建视图上添加?另外,是否有一个原因,我不得不重构你提到的功能。 – Brian