ASP.NET MVC: הוספת פריט חדש שמקושר לכמה טבלאות
-
יש לי פרוייקט של ספרייה. כל ספר יש לו מאפיין של שם המחבר ושל הקטגוריה שלו. שני המאפיינים הללו הם בעצם אובייקט נפרד ממחלקה של מחברים, וקטגוריות.
בתצוגה האוט' שנוצרה לי היא לא כללה את המאפיינים הללו (כי הם לא חלק מהטבלה בDB, אלא מפתח זר). לכן הוספתי בתצוגה גם אותם. אולם זה לא עוזר, כיון שכדי ליצור את האובייקט אני בעצם צריך לעדכן גם את 2 הטבלאות הללו.אני רוצה, שכשהוא טוען את התצוגה הוא יציג ברשימה נפתח כבר את הפריטים הקיימים בטבלאות הללו (כדי שהמשתמש יוכל לבחור ממחברים קיימים או להוסיף חדש).
לכן כתבתי את הקוד הבא במתודה Create:// GET: Books/Create public ActionResult Create() { Book book = new Book(); ViewBag.Model = book; ViewBag.Model.AuthorsName1.AuthorName = new SelectList(db.Authors, "", "AuthorsName"); ViewBag.Model.AuthorsName2.AuthorName = new SelectList(db.Authors, "", "AuthorsName"); ViewBag.Model.Subject.Subject = new SelectList(db.SubjectBooks, "", "Subject"); return View(); }
אולם אני מקבל שגיאת ריצה: "לא ניתן לבצע איגוד זמן ריצה בהפניה לערך Null". מי פירוש NULL? הרי בדטהבייס יש נתונים?
כמו כן,
כיצד במתודת הPOST (ששולחת את הנתונים שהזין המשתמש) אני יכול להריץ שאילתא על הטבלאות הנוספות לבדוק אם הערך שהוא הזין קיים בהם, ואם לא להוסיף חדש?
כתבתי כך:[HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include = "Id,Title,Expenditure,YearOfPublication,Release")] Book book) { if (ModelState.IsValid) { var authors1 = db.Authors.Where(x => x.AuthorName.Contains(book.AuthorsName1.AuthorName)); var authors2 = db.Authors.Where(x => x.AuthorName.Contains(book.AuthorsName2.AuthorName)); var subject = db.SubjectBooks.Where(x => x.Subject.Contains(book.Subject.Subject)); if (!authors1.Equals(book.AuthorsName1.AuthorName)) db.Authors.Add(book.AuthorsName1); if (!authors2.Equals(book.AuthorsName2.AuthorName)) db.Authors.Add(book.AuthorsName2); if (!subject.Equals(book.Subject.Subject)) db.SubjectBooks.Add(book.Subject); db.Books.Add(book); db.SaveChanges(); return RedirectToAction("Index"); } return View(book); }
אבל זה לא עובד.. אני כל הזמן מקבל שגיאה שהערכים הללו (מחברים ונושא) הם ערכי חובה (מהשרת, לא מהAJAX). כלומר, זה אומר שהוא לא הצליח להזין אותם לשרת..
אשמח לעצות והארות!
תודה רבה!פורסם במקור בפורום CODE613 ב18/10/2015 14:56 (+03:00)
-
א. המחלקה book:
public class Book { public int Id { get; set; } [Required(ErrorMessage ="{0} הינו שדה חובה")] [Display(Name ="שם הספר")] public string Title { get; set; } [Required(ErrorMessage = "{0} הינו שדה חובה")] [Display(Name ="שם המחבר")] public Author AuthorsName1 { get; set; } [Display(Name = "מחבר נוסף")] public Author AuthorsName2 { get; set; } [Required(ErrorMessage = "{0} הינו שדה חובה")] [Display(Name ="שם ההוצאה")] public string Expenditure { get; set; } [Display(Name ="שנת הוצאה לאור")] public int YearOfPublication { get; set; } [Display(Name ="מהדורה")] public double Release { get; set; } [Required(ErrorMessage = "{0} הינו שדה חובה")] [Display(Name ="תחום")] public SubjectBooks Subject { get; set; } }
ב. נתונים ודאי יש בו. לגבי הקונסטרוקטר שלו באמת הוא ריק, אבל הוא ריק גם מהDB של הBook, ואפי' הכי הוא מציג אותם?!
הנה הקוד שלו:public class LibraryBooksContext : DbContext { public LibraryBooksContext() : base("name=LibraryBooksContext") { } public DbSet<CatalogBooks> CatalogBooks { get; set; } public DbSet<Author> Authors { get; set; } public DbSet<SubjectBooks> SubjectBooks { get; set; } public DbSet<Book> Books { get; set; } public DbSet<LocationBook> LocationBooks { get; set; } }
להוסיף בבנאי שורה שיורצת מופע שלו?
כי בקוד של הקונטרולר מופיעה רק השורה הבאה:private LibraryBooksContext db = new LibraryBooksContext();
פורסם במקור בפורום CODE613 ב19/10/2015 13:05 (+03:00)
-
לגבי שאלתי השניה ענית לי די באריכות כי מה שהיה חשוב לי זה הקוד האחרון, בקיצור המשתנה db מאותחל.
לגבי הראשונה, אני מבין שהמאפיין AuthorName של המחלקה Author הוא מטיפוס סטרינג, כך שלא שייך לשים בו SelectList. עדיין זה לא מסביר את לשון השגיאה אבל זה ודאי שגוי.
עליך לכתוב ככה:// GET: Books/Create public ActionResult Create() { Book book = new Book(); ViewBag.Model = book; ViewBag.AutorsList = new SelectList(db.Authors, "", "AuthorsName"); ViewBag.SubjectsList = new SelectList(db.SubjectBooks, "", "Subject"); return View(); }
שורות 6-7 זה פשוט רשימת ערכים שמועברת לדף בשביל ליצור DropDownList. זה לא חל מהמודל, שהרי המודל לא מכיל שום רשימה הוא מכיל את השם [u:1oisjzv5]שנבחר[/u:1oisjzv5]. זה מוכנס למשתנים דינמיים בכל שם שתבחר. בView תצטרך להשתמש בDropDownList ולתת לה כפרמטר את הModel.AutorList בכל מקום שתבחר.
פורסם במקור בפורום CODE613 ב19/10/2015 13:54 (+03:00)
-
@דוד ל.ט.
בView תצטרך להשתמש בDropDownList ולתת לה כפרמטר את הModel.AutorList בכל מקום שתבחר.
תודה רבה!
שתי שאלות:
א. האם הDropDownList נותן אפשרות למשתמש להזין אליו גם ערכים נוספים, ואם לא - האם יש משהו אחר שכן נותן? כיון שאני רוצה שיוכל לבחור מהקיים או להוסיף חדש (או שאת זה עושים עם Ajax?)ב. אני לא בדיוק מבין אלו ערכים נוספים אני צריך להזין בview כשאני מגדיר את הDropDownList וכיצד?
תודה רבה רבה מראש!!
פורסם במקור בפורום CODE613 ב19/10/2015 15:04 (+03:00)
-
א. האם הDropDownList נותן אפשרות למשתמש להזין אליו גם ערכים נוספים, ואם לא - האם יש משהו אחר שכן נותן? כיון שאני רוצה שיוכל לבחור מהקיים או להוסיף חדש (או שאת זה עושים עם Ajax?)
הDropDownList מייצר תגית select של html. התגית הזאת לא מאפשרת הקלדה - רק בחירה מהרשימה.
אבל כמובן אפשר לשכלל את הפרימיטיביות הזאת:
http://stackoverflow.com/questions/4430262/manually-type-in-a-value-in-a-select-drop-down-html-list
התשובה הראשונה מציעה תוסף של jQuery שנותן תיבה משולבת - ComboBox, השניה מציעה דרך שנותן חוויה אחרת: יש ברשימה אפשרות למותאם אישית וכאשר היא נבחרת ניתנת תיבת טקסט לכתוב בה. זה חווית משתמש מתאימה למקרים שאתה מעוניין 1. שאנשים יבחרו ככל האפשר בערך קיים. או 2. שאנשים ימעטו בהקלדה ידנית של ערכים (שעלולה להכיל שגיאות כתיב וכו').ב. אני לא בדיוק מבין אלו ערכים נוספים אני צריך להזין בview כשאני מגדיר את הDropDownList וכיצד?
@Html.DropDownList("AuthorsName1", (SelectList)ViewBag.AutorsList) @Html.DropDownList("AuthorsName2", (SelectList)ViewBag.AutorsList) @Html.DropDownList("Subject", (SelectList)ViewBag.SubjectsList)
פורסם במקור בפורום CODE613 ב20/10/2015 12:04 (+03:00)