שואל
קישור בין view ל controller ב mvc כאשר יש בview שימוש של רשימה מדובר ב create controller

שאלה
-
שלום,
אני יוצרת את האתר הראשון שלי בmvc ב C#
אני השתמשתי ב entity framework
מסד הנתונים שלי הוא כנ"ל:
אני יצרתי את modeld וה controllers ואת הview באופן אוטומטי.
אך אני רציתי שכאשר אדם ירצה ליצור אוביקט של מוצר לחנות אז הוא יוכל לבחור את החנות מתוך רשימה וכנ"ל גם את המוצר מתוך רשימת מוצרים.
לכן יצרתי מחלקה חדשה שלה יש רשימה של מוצרים ורשימה של חנויות.
אך נתקעתי בview , אומנם הצלחתי שיראו את הרשימה של החנויות ושל ושל המוצרים , אך אני רוצה שכאשר האדם יבחר את שם החנות אני אוכל לשמור את שם החנות וכנ"ל לגבי שם המוצר ולהוסיף אותם לdatabase,
להלן קוד מצורף:
הקוד של ה view כאו אני מציגה את שמות החנויות
<div class="form-group"> <select id="Select1"> @foreach (var item in Model.ShopList) { <option>@item.nameShop </option> } </select> </div>
הקוד של הcontroller
public ActionResult Create( proToShopFull pts) { try { // TODO: Add insert logic here pts.addToData(); return RedirectToAction("Index"); } catch { return View(); } }
אשמח לקבל קישור למדריכים ב mvc
- נערך על-ידי שמיים כחולים יום רביעי 26 יולי 2017 18:29
כל התגובות
-
תבדקי את המדריך הבא:
https://www.codeproject.com/Articles/1078491/Creating-Forms-in-ASP-NET-MVCהוא נחמד מאוד מכיוון שהוא מראה בכל שלב מה קורה בצד הלקוח ומה את צריכה לעשות בצד השרת
* אין קשר ל entity framework ולשאלה שלך אם הבנתי את השאלה נכון. כל העניין הוא כיצד ליצור את הטופס כך שאנשים יוכלו לבחור משהו והנתונים יועברו לשרת. החלק של ה entity framework מתקשר רק לשלב של מה קורה בצד השרת (וזה לא קשור לחלק של ה view כמובן)
Ronen Ariely
[Personal Site] [Blog] [Facebook] [Linkedin] -
שלום,
קראתי את המדריך וזה עזר לי להבין יותר לעומק את הרעיון של mvc
אבל בכל אופן יש לי שאלה ספציפית. אני רוצה להציג רשימה ב veiw. הרשימה הינה חלק ממודל.
אני רוצה לדעת איך משתמשים באוביקט של הצגת רשימה בmvc תוך התיחסות ל selectedItem
למעלה כתבתי איך הצלחתי להציג את הרשימה אבל לא הצלחתי להשתמש באפשרות כאשר בוחרים אוביקט ברשימה אז הערך ייכנס למודל.
ניסיתי גם את הקוד הנ"ל וזה לא עזר:
<div class="form-group"> <h1>pro</h1> <div class="col-md-10"> @Html.DropDownListFor(model => model.Ps.IdProduct, (IEnumerable<SelectListItem>)Model.ProductsList, new { @class = "form-control" }) </div> </div>
-
-
-
היי,
האם בצד הלקוח את רואה את הרשימה?
הבחירה של האלמנט מהרשימה לא קשור לצד השרת אלא לצד הלקוח
זה אמור להיות טופס HTML פשוט בצד הלקוח
אחרי שאת בוחרת את הנתון מהרשימה ושולחת את הטופס הוא אמור להגיע לשרת כמו fל אלמנט בטופס
הרעיון של ה שימוש במודולים כמו @Html.DropDownListFor הוא בסך הכל יצירת הרימה והקוד של ה HTMK בצד הלקוח
* קוד ה HTML וה JS גם כןאני לא בטוח לכן מה את מתכוונת.
את יכולה לצרף את קוד ה HTML של העמוד שנוצר לך?
האם הרשימה ניראית בטופס?
באיזה שלב את רוצה לשלוח לשרת את התוצאה של הבחירה של הרשימה - האם בזמן שליחת הטופס או בזמן הבחירה בצורבה ניסתרת (מה שאומר שיש שימוש ב AJAX)
Ronen Ariely
[Personal Site] [Blog] [Facebook] [Linkedin]- נערך על-ידי pituachMVP, Moderator יום שלישי 22 אוגוסט 2017 06:22
-
היי,
הבעיה שלי היא בצד של הלקוח ולא של השרת.
אני רוצה שתוצג הרשימה בזמן היצירה של דף ה-html
ואז אני בוחרת שם מוצר מתוך הרשימה ושם חנות מהרשימה ומוסיפה עוד פרטים כמו מספר מוצרים וכו'
ואז כשאני אלחץ על ה-sumbit הבחירה תישלח לשרת.
אבל מה גם אני צריכה לשמור על id של המוצר שנבחר ועל id של החנות שנבחרה. כי מה שאני שולחת לשרת זה את ה id ולא את השם.
אני הצלחתי רק להציג את הרשימה אבל בלי אפשרות של בחירה.
אני מצרפת את הקוד של ה-html.
יש כאן ניסויים שלא הצליחו. הצלחתי רק להציג את הרשימה כפי שציינתי למעלה.
@model shop.Models.proToShopFull @{ ViewBag.Title = "Create"; Layout = "~/Views/Shared/_Layout.cshtml"; } @using (Html.BeginForm()) { @Html.AntiForgeryToken() <h2>Create</h2> <div class="form-horizontal"> <h4>proToShopFull</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Create" class="btn btn-default" /> </div> </div> <div class="form-group"> <select id="Select1"> @foreach (var item in Model.ShopList) { <option>@item.nameShop </option> } </select> </div> <div class="form-group"> <select id="Select2"> @foreach (var item in Model.ProductsList) { @Html.DisplayNameFor(modelItem => @item.nameProduct) @*<option>@item.nameProduct </option>*@ @*<option> @Html.DisplayNameFor(modelItem => @item.nameProduct)</option>*@ @*<option >@Html.EditorFor(model => model.Ps .IdProduct, @item.nameProduct)</option>*@ } </select> </div> </div> <div class="form-group"> <h1>pro</h1> <div class="col-md-10"> @Html.DropDownListFor(model => model.Ps.IdProduct, (IEnumerable<SelectListItem>)Model.ProductsList, new { @class = "form-control" }) @*@Html.EditorFor(model => model.Ps.amount, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Ps.amount, "", new { @class = "text-danger" })*@ </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Ps.amount, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Ps.amount, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Ps.amount, "", new { @class = "text-danger" }) </div> </div> } <div> @Html.ActionLink("Back to List", "Index") </div> @section Scripts { @Scripts.Render("~/bundles/jqueryval") }
הקוד שכן עובד זה:
<div class="form-group"> <select id="Select1"> @foreach (var item in Model.ShopList) { <option>@item.nameShop </option> } </select> </div>
תודה רבה רבה
-
דבר ראשון - ראיתי שאת קובעת את ה-Layout בתצוגה עצמה. בעיקרון עדיף לבחור אותו בקובץ Views\_ViewStart.cshtml\~ (כך הפריסה נקבעת לכל התצוגות). זוהי גם ברירת המחדל בפרוייקט חדש ב-VS. מדוע שינית זאת?
אמרת שהלולאה שלך לא עובדת:
<select id="Select1"> @foreach (var item in Model.ShopList) { <option>@item.nameShop </option> } </select>
אבל בכלל לא קבעת ל-select ב-name את השם של המאפיין שאמור להישלח לשרת!
אסביר: מנגנון הקישור למודל (Model Binding) של MVC פועל כך שכאשר הוא מזהה בטופס שנשלח לשרת שדה מקביל בשמו לשם של פרמטר של שיטת הפעולה (או חלק ממנו כמו בדוגמה הנ"ל, שיש אובייקט מסוג proToShopFull לשיטת הפעולה, והוא מגלה מאפיין שלו בעל שם תואם לשדה שנשלח) הוא מציב במאפיין את ערך השדה (לאחר המרה, אם נצרכת).
כידוע, הערך של המאפיין name הוא השם שישלח לשרת בתור שם השדה. לכן אם לא סיפקת לו ערך, המקשר למודל לא יציב בו את הערך הנכון! (ייתכן שכדאי לך לחפש באינטרנט יותר חומר על כיצד פועלת תשתית MVC "מאחורי הקלעים").
בנוסף, לתג option יש תכונה בשם value. ערך התכונה הזו הוא הערך שישלח לשרת כאשר המשתמש בחר באפשרות זו מתוך הרשימה. כאשר תכונה זו לא מוגדרת, הערך שמוצב בתוך התג הוא גם הערך שישלח לשרת. פלא שרק השמות ולא הקודים נשלחים לשרת?
את יכולה להשתמש בקוד מעין זה:
<select id="Select1"> @foreach (var item in Model.ShopList) { <option value="@item.idShop">@item.nameShop </option> } </select>
בהנחה שקיים במודל שלך מאפיין בשם idShop שהוא ה-id של החנות :-)
אם לא עזרתי לך, אולי כדאי שתספקי יותר מידע (כגון איך מוגדרים המודלים שלך) ואפילו תעלי את הפרוייקט למקום כלשהוא ותשלחי לנו קישור (-:
-
היי,
ניסיתי את זה וזה לא הלך לי.
אני עקבתי אחרי זה וראיתי ב create שהערך של קוד החנות הוא 0.
טוב, אז אני אצרף לכם את תאור המחלקות.
המחלקות שלי הם:
יש לי 3 מחלקות שנוצרו לי אוטומטית והם:
1. shop- מחלקה עם פרטי החנות
2. product- מחלקה המכילה את פרטי המוצר
3. proToShop- המחלקה המציינת את הקשר בין מוצר לחנות. התוכנה מיועדת עבור ספקים אשר רוצים לסדר להם מידע של הזמנות מוצרים לחנויות. וזה קשר של רבים לרבים.
כל התצוגות נוצרו לי אוטומטית אבל אני רציתי שכאשר אני אוסיף הזמנה חדשה אז אני אוכל לבחור את שם החנות ואת שם המוצר מתוך רשימה ולא להשתמש בקודים.
לכן יצרתי מחלקה חדשה ששמה proToShopFull . והיא מכילה רשימה של כל המוצרים וכן רשימה של כל החנויות וכן אוביקט מסוג proToShop.
וכן יצרתי controller ו view חדשים. הקוד של הhtml שלמעלה, זה הקוד של הview עבור המודל proToShopFull
להלן המחלקות:
shop
public partial class Shops { [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public Shops() { this.proToShop = new HashSet<proToShop>(); } public int ShopsId { get; set; } public string nameShop { get; set; } public string adress { get; set; } public string telephone { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<proToShop> proToShop { get; set; } }
product
public partial class products { [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public products() { this.proToShop = new HashSet<proToShop>(); } public int productsId { get; set; } //[Required(ErrorMessage = "name product is required")] public string nameProduct { get; set; } public Nullable<decimal> price { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<proToShop> proToShop { get; set; } }
proToShop
public partial class proToShop { public int Id { get; set; } public int IdShop { get; set; } public int IdProduct { get; set; } public Nullable<int> amount { get; set; } public string price { get; set; } public virtual products products { get; set; } public virtual Shops Shops { get; set; } }
proToShopFull
public class proToShopFull { private ApplicationDbContext db = new ApplicationDbContext(); private int shopsId; public int ShopsId { get { return shopsId; } set { shopsId = value; } } private proToShop ps; public proToShop Ps { get { return ps; } set { ps = value; } } private Double price; public Double Price { get { return price; } set { price = value; } } private List<Shops> shopList; public List<Shops> ShopList { get { return shopList; } set { shopList = value; } } private List<products> productsList; public List<products> ProductsList { get { return productsList; } set { productsList = value; } } public proToShopFull() { ps = new Models.proToShop(); shopList = new List<Models.Shops>(); foreach (var item in db.Shops) { shopList.Add(item ); } ProductsList = new List<products>(); foreach (var item in db.products) { ProductsList.Add(item); } } internal void addToData() { throw new NotImplementedException(); } public void setAmount(int value) { ps.amount = value; ps.price = (value * 2).ToString(); } public IEnumerable<SelectListItem> getSelectedItemListPro() { List<SelectListItem> list=new List <SelectListItem>(); foreach (var item in productsList) { list.Add(new SelectListItem { Value =item .productsId.ToString() , Text = item.nameProduct }); } return list; }
proToShopFullController
// GET: proToShopFull/Create public ActionResult Create() { proToShopFull ps = new Models.proToShopFull(); return View(ps); } // POST: proToShopFull/Create [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create( proToShopFull pts) { try { // TODO: Add insert logic here pts.addToData(); return RedirectToAction("Index"); } catch { return View(); } }
תודה רבה
-
הערה: את משתמשת באסטרטגיות שונות למתן שמות למשתנים, וזה ממש ממש מבלבל והופך את הקוד ללא קריא. קחי לתשומת ליבך :-)
דבר ראשון: הקוד שכתבתי כדוגמה נועד לתת הסבר אך ורק על ה-value ל-options ולא על ה-name. דוגמה מלאה יכולה להיות כזו:
<select id="ShopsId" name="ShopsId"> @foreach (var item in Model.ShopList) { <option value="@item.ShopsId">@item.nameShop</option> } </select>
מצטער, אני חייב ע כ ש י ו לעוף מהמחשב, עוד איזה שעתיים ככה אני אמשיך את התשובה (-:
-
-