2016-03-19 9 views
0

Ich erstelle ein Ticketsystem, bei dem Benutzer auf der Ticketseite gehen und Tickets erstellen, wenn sie Probleme haben. Es ist eine MVC4 mit EF6 Web-Anwendung und ich habe Fehler, die ich wegen mangelndem Wissen über MVC nicht lösen kann.MVC Die INSERT-Anweisung widerspricht der FOREIGN KEY-Einschränkung "FK_dbo.Ticket_dbo.User_UserID"

Ich habe folgende Anweisungen von einer Person:

In meiner früheren Version von meinem Code hatte ich eine andere Drop-Down-Liste für Benutzer, wurde aber darauf hingewiesen, dass es falsch war.

Sie erstellen ein neues Ticket, und dieses Ticket sollte dem aktuellen Benutzer zugewiesen werden. Der aktuelle Benutzer sollte kein Ticket für einen anderen Benutzer erstellen können. Sie sollten nicht einmal eine Dropdown-Liste für diese Eigenschaft haben. Sie weisen den Wert von Author (oder UserID`) nur in der Methode POST kurz vor dem Speichern des Datenmodells zu.

Also nahm ich meine Dropdown-Liste für Benutzer, wie Sie aus dem zweiten Bild unten sehen können. Ich habe auch Author = model.UserID, wenn ich mein Ticket erstellen:

 Ticket ticket = new Ticket 
     { 
      Author = model.UserID, 
      Issue = model.Issue, 
      IssuedTo = model.IssuedTo, 
      CategoryID = model.CategoryID 
     }; 

Ihr erstes, wenn korrekt, außer dass Sie die ConfigureViewModel() -Methode Änderung müssen auch die für Kategorien des Select erstellen (ModelState.IsValid!) . Dann erstellen Sie das Ticketdatenmodell und Sie müssen alle seine Eigenschaften einschließlich CategoryID festlegen.

Also habe ich den Code, der eine SelectList oder Kategorien in meiner ConfigureViewModel-Methode sein sollte.

IEnumerable<Category> categories = db.Categories.OrderBy(u => u.CategoryName); 
    model.CategoryList = categories.Select(a => new SelectListItem 
    { 
     Value = a.CategoryID.ToString(), 
     Text = a.CategoryName.ToString() 
    }); 

Dann, wenn Sie db.SaveChanges() aufrufen, müssen Sie umleiten. Es gibt keine Punkt aufrufen Rückkehr View(); und wenn Sie das tun, dann wird es einfach starten wirft Fehler, weil Sie die SelectLists nicht gefüllt haben.

Dieser Teil war ich nicht so sicher über "Redirect". Wenn ich Rückkehr Ansicht löschen() Ich erhalte eine Fehlermeldung auf public ActionResult Create(TicketVM model) sagen TicketController.Create(TicketVM) nicht alle Codepfade zurückkehren ein value`

Die INSERT-Anweisung in Konflikt mit der FOREIGN KEY-Einschränkung „FK_dbo.Ticket_dbo.User_UserID“. Der Konflikt ist in der Datenbank "RecreationalServicesTicketingSystem.DAL.IssueContext", Tabelle "dbo.User", Spalte "UserID" aufgetreten. Die Anweisung wurde beendet.

enter image description here enter image description here

TicketController.cs (POST-Methode SNIPPET)

namespace RecreationalServicesTicketingSystem.Controllers 
{ 
    public class TicketController : Controller 
    { 
     private IssueContext db = new IssueContext(); 

     // 
     // GET: /Ticket/Create 

     public ActionResult Create() 
     { 

      TicketVM model = new TicketVM(); 
      ConfigureViewModel(model); 
      ViewBag.CategoryID = new SelectList(db.Categories, "CategoryID", "CategoryName"); 
      ViewBag.AllUsers = db.Users.ToList().Select(u => new SelectListItem() { Value = u.UserID.ToString(), Text = string.Format("{0} {1}", u.FirstMidName, u.LastName) }); 
      return View(model); 
     } 

     // 
     // POST: /Ticket/Create 

     [HttpPost] 
     [ValidateAntiForgeryToken] 
     public ActionResult Create(TicketVM model) 
     { 


      if (!ModelState.IsValid) 
      { 
       ConfigureViewModel(model); 
       return View(model); 
      } 

      Ticket ticket = new Ticket 
      { 
       Author = model.UserID, 
       Issue = model.Issue, 
       IssuedTo = model.IssuedTo, 
       CategoryID = model.CategoryID 
      }; 

       db.Tickets.Add(ticket); 
       db.SaveChanges(); 


      ViewBag.CategoryID = new SelectList(db.Categories, "CategoryID", "CategoryName", ticket.CategoryID); 
    //   ViewBag.AllUsers = db.Users.ToList().Select(u => new SelectListItem() { Value = u.UserID.ToString(), Text = string.Format("{0} {1}", u.FirstMidName, u.LastName) }); 
//   ViewBag.AllAdmins = db.Users.Where(u => u.IsAdministrator).Include(u => u.Tickets); 
      return View(ticket); 
     } 

     private void ConfigureViewModel(TicketVM model) 
     { 
      IEnumerable<User> admins = db.Users.Where(u => u.IsAdministrator).OrderBy(u => u.LastName); 
      model.AdministratorList = admins.Select(a => new SelectListItem 
      { 
       Value = a.UserID.ToString(), 
       Text = string.Format("{0} {1}", a.FirstMidName, a.LastName) 
      }); 
      IEnumerable<Category> categories = db.Categories.OrderBy(u => u.CategoryName); 
      model.CategoryList = categories.Select(a => new SelectListItem 
      { 
       Value = a.CategoryID.ToString(), 
       Text = a.CategoryName.ToString() 
      }); 
     } 

Ansichten \ Ticket \ erstellen.cshtml

@model RecreationalServicesTicketingSystem.ViewModels.TicketVM 

@{ 
    ViewBag.Title = "Create"; 
} 

<h2>Create</h2> 

@using (Html.BeginForm()) { 
    @Html.AntiForgeryToken() 
    @Html.ValidationSummary(true) 

    <fieldset> 
     <legend>Ticket</legend> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.CategoryID, "Category") 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownList("CategoryID", String.Empty) 
      @Html.ValidationMessageFor(model => model.CategoryID) 
     </div> 

     <div class="editor-field"> 
      @using (Html.BeginForm()) 
      { 
       @Html.HiddenFor(m => m.UserID) 
       <div class="form-group"> 
        @Html.LabelFor(m => m.IssuedTo) 
        @Html.DropDownListFor(m => m.IssuedTo, Model.AdministratorList, "Please select", new { @class = "form-control" }) 
        @Html.ValidationMessageFor(m => m.IssuedTo) 
       </div> 
       <div class="form-group"> 
        @Html.LabelFor(m => m.Issue) 
        @Html.TextBoxFor(m => m.Issue, new { @class = "form-control" }) 
        @Html.ValidationMessageFor(m => m.Issue) 
       </div> 
      } 
     </div> 
     <p> 
      <input type="submit" value="Create" /> 
     </p> 
</fieldset> 
} 

<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

@section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 
} 

!!!!!!!!!!!!!!! ÄNDERUNGEN AN CODE !!!!!!!!!!!!!!!!!!!!!!!! !

TicketController.cs

public class TicketController : Controller 
{ 
    private IssueContext db = new IssueContext(); 

    // 
    // GET: /Ticket/ 

    public ActionResult Index() 
    { 
     var tickets = db.Tickets.Include(t => t.Category).Include(t => t.User);  
     return View(tickets.ToList()); 
    } 

    // 
    // GET: /Ticket/Details/5 

    public ActionResult Details(int id = 0) 
    { 
     Ticket ticket = db.Tickets.Find(id); 
     if (ticket == null) 
     { 
      return HttpNotFound(); 
     } 
     return View(ticket); 
    } 

    // 
    // GET: /Ticket/Create 

    public ActionResult Create() 
    { 
     TicketVM model = new TicketVM(); 
     ConfigureViewModel(model); 
     return View(model); 
    } 

    // 
    // POST: /Ticket/Create 

    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Create(TicketVM model) 
    { 


     if (!ModelState.IsValid) 
     { 
      ConfigureViewModel(model); 
      return View(model); 
     } 

     Ticket ticket = new Ticket 
     { 
      //UserID = (int)WebSecurity.CurrentUserId, 
      // Author = model.UserID, 
      Issue = model.Issue, 
      IssuedTo = model.IssuedTo, 
      CategoryID = model.CategoryID 
     }; 

      db.Tickets.Add(ticket); 
      db.SaveChanges(); 

     return RedirectToAction("Index"); 

    } 

    private void ConfigureViewModel(TicketVM model) 
    { 
     IEnumerable<User> admins = db.Users.Where(u => u.IsAdministrator).OrderBy(u => u.LastName); 
     model.AdministratorList = admins.Select(a => new SelectListItem 
     { 
      Value = a.UserID.ToString(), 
      Text = string.Format("{0} {1}", a.FirstMidName, a.LastName) 
     }); 
     IEnumerable<Category> categories = db.Categories.OrderBy(u => u.CategoryName); 
     model.CategoryList = categories.Select(a => new SelectListItem 
     { 
      Value = a.CategoryID.ToString(), 
      Text = a.CategoryName.ToString() 
     }); 
    } 

    // 
    // GET: /Ticket/Edit/5 

    public ActionResult Edit(int id = 0) 
    { 
     Ticket ticket = db.Tickets.Find(id); 
     if (ticket == null) 
     { 
      return HttpNotFound(); 
     } 
     ViewBag.AllAdmins = db.Users.Where(u => u.IsAdministrator).Include(u => u.Tickets); 
     return View(ticket); 
    } 

    // 
    // POST: /Ticket/Edit/5 

    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Edit(Ticket ticket) 
    { 
     if (ModelState.IsValid) 
     { 
      db.Entry(ticket).State = EntityState.Modified; 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     ViewBag.AllAdmins = db.Users.Where(u => u.IsAdministrator).Include(u => u.Tickets); 
     return View(ticket); 
    } 

Ansichten \ Ticket \ Create.cshtml

@model RecreationalServicesTicketingSystem.ViewModels.TicketVM 

@{ 
    ViewBag.Title = "Create"; 
} 

<h2>Create</h2> 

@using (Html.BeginForm()) { 
    @Html.AntiForgeryToken() 
    @Html.ValidationSummary(true) 

    <fieldset> 
     <legend>Ticket</legend> 

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


     <div class="editor-field"> 
      @using (Html.BeginForm()) 
      { 
       @Html.HiddenFor(m => m.UserID) 
       <div class="form-group"> 
        @Html.DropDownListFor(m => m.CategoryID, Model.CategoryList, "Please select", new { @class = "form-control" }) 
       </div> 
       <div class="form-group"> 
        @Html.LabelFor(m => m.IssuedTo) 
        @Html.DropDownListFor(m => m.IssuedTo, Model.AdministratorList, "Please select", new { @class = "form-control" }) 
        @Html.ValidationMessageFor(m => m.IssuedTo) 
       </div> 
       <div class="form-group"> 
        @Html.LabelFor(m => m.Issue) 
        @Html.TextBoxFor(m => m.Issue, new { @class = "form-control" }) 
        @Html.ValidationMessageFor(m => m.Issue) 
       </div> 
      } 
     </div> 
     <p> 
      <input type="submit" value="Create" /> 
     </p> 
</fieldset> 
} 

<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

@section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 
} 
+1

Q1: Siehe Hinweis auf Ihre andere Frage (und entfernen Sie 'ViewBag.AllUsers = ....' von der GET-Methode –

+1

Q2: Ihr überarbeiteter Code in der 'ConfigureViewModel()' Methode ist korrekt, außer entfernen 'ViewBag.CategoryID = new SelectList (...) 'aus der GET-Methode und der POST-Methode und ändere den View-Code in' @ Html.DropDownListFor (m => m.CategoryId, Model.CategoryList, "Bitte auswählen", new {@class = " form-control "})' und verschiebe es in die Form-Tags. –

+1

Q3: Ändere 'return View (ticket);' um 'RedirectToAction (" Index ");' zurückzugeben (oder welche Ansicht du auch immer anzeigen willst) erfolgreich das 'Ticket' gespeichert –

Antwort

0

Der Fehler, dass Ticket_dbo Sie versuchen, eine Benutzer-ID in die Spalte User_UserID einzufügen, aber dieser Benutzer in der Tabelle zu sagen hat ID existiert nicht in der Tabelle dbo.User. So funktionieren Fremdschlüsseleinschränkungen. Stellen Sie daher sicher, dass Sie den Benutzer zuerst in die Datenbank einfügen, oder prüfen Sie, ob dieser Benutzer vorhanden ist. Falls nicht, gehen Sie dann entsprechend Ihren Anforderungen vor.

Dann, wenn Sie db.SaveChanges() aufrufen, müssen Sie umleiten. Es gibt keinen Punkt Aufruf Rückkehr View(); und wenn Sie das tun, wird es nur Fehler werfen, weil Sie die SelectLists nicht gefüllt haben.

Ja, er/sie hat Recht. Sie sollten nicht einfach eine Ansicht zurückgeben. Senden Sie eine Weiterleitung, damit der Browser eine andere Seite abrufen kann. Here ist, wie und warum Sie das tun sollten.

Verwandte Themen