MVC Html .DropDownListFor возвращает сложный тип с нулевыми значениями - PullRequest
0 голосов
/ 24 февраля 2020

У меня есть следующее действие создания контроллера в моем контроллере. Необходимо, чтобы отображаемое имя в списке выбора было «StoreName - StoreAddress». Store complexType хранится в Store.

        // GET: Purchases/Create
        public ActionResult Create()
        {
            ViewBag.Stores = db.Stores.Select(s => new { DisplayName = s.StoreName.ToString() + " - " + s.Address.ToString(), Store = s});

            return View();
        }

В представлении «Создать» следующий код заботится о том, чтобы он отображался правильно.

    <div class="form-group">
        @Html.LabelFor(model => model.Store.StoreName, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(model => model.Store.StoreName, new SelectList(ViewBag.Stores, "Store", "DisplayName"), new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.Store.StoreName, "", new { @class = "text-danger" })
        </div>
    </div>

Это будет go методу post контроллера (если я прав).

        // POST: Purchases/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see https://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,Store,Price,Date")] Purchase purchase)
        {
            if (ModelState.IsValid)
            {
                Store store = purchase.Store;

                db.Purchases.Add(purchase);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(purchase);
        }

Однако Store store = purchase.Store теперь выдаст комплекс Тип хранилища со значениями для чего-либо кроме StoreName, установленного в нуль. StoreName будет строкой.

Как получить возвращенный сложный тип, равный выбранному объекту Store?


Редактировать 1:

public class Purchase
   {
       public int Id { get; set; }

       public Store Store { get; set; }

       public string Type { get; set; }

       [DataType(DataType.Currency)]
       [Column(TypeName = "money")]
       public decimal Price { get; set; }

       [DataType(DataType.Date)]
       [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
       public DateTime Date { get; set; }
   }

public class PurchaseDBContext : DbContext
   {
       public DbSet<Purchase> Purchases { get; set; }
       public DbSet<Store> Stores { get; set; }

       protected override void OnModelCreating(DbModelBuilder modelBuilder)
       {

       }
   }
public class Store
    {
        public int StoreId { get; set; }

        public string StoreName { get; set; }

        public string Address { get; set; }

        public string City { get; set; }

        [DataType(DataType.PhoneNumber)]
        [RegularExpression(@"^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9])((\s|\s?-\s?)?[0-9])((\s|\s?-\s?)?[0-9])\s?[0-9]\s?[0-9]\s?[0-9]\s?[0-9]\s?[0-9]$", ErrorMessage = "This is not a valid phonenumber")]
        public string PhoneNumber { get; set; }

    }

Нужно ли мне использовать дополнительные аннотации для установки свойств навигации?

1 Ответ

0 голосов
/ 25 февраля 2020

В вашем примере много чего происходит, но нет необходимости передавать сложный объект, если вы используете свойства навигации и ваша модель настроена определенным образом. Если вы настроите свойство навигации для Store / StoreId, Entity Framework должен сделать выводы для вас, так что это упростит ваше представление.

public class Purchase 
{
    public int StoreId { get; set; }
    [ForeignKey("StoreId")]
    public Store Store { get; set;}
}

Я передам модель представлению, подобному приведенному ниже. ИМО, он чище, чем использование ViewBag.

public class CreatePurchaseModel
{
    //To populate a list
    public List<Store> AvailableStores { get; set; }
    //The actual object to be created
    public Purchase Purchase { get; set; }
}

Метод контроллера:

// GET: Purchases/Create
public ActionResult Create()
{
    var vm = new CreatePurchaseModel() 
    {
        AvailableStores = db.Stores.ToList(),
        Purchase = new Purchase()
    };

    return View(vm);     
}

Заполните раскрывающийся список свойством AvailableStores, чтобы установить Purchase.StoreId

@Html.DropDownListFor(m => m.Purchase.StoreId, Model.AvailableStores.Select(x => new SelectListItem { Text = x.StoreName.ToString(), Value = x.StoreId.ToString() }))

Если он настроен правильно, все, что вам нужно в параметрах метода записи, это покупка

[ValidateAntiForgeryToken, HttpPost]
public ActionResult Create(Purchase purchase) 
{
    //purchase.StoreId should have a non zero value
    db.Purchases.Add(purchase);
    db.SaveChanges();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...