@ Html.DropDownListFor привязка, приводящая к ошибке «Преобразование параметра из типа System.String в тип» - PullRequest
0 голосов
/ 03 апреля 2019

Я просто пытаюсь привязать @ Html.DropDownListFor к моей модели представления, и каждый раз, когда я добавляю новый продукт, я получаю сообщение об ошибке:

"Преобразование параметра из типа"Ошибка System.String для типа «SuperStockpile.Core.Models.Brand», поскольку преобразователь типов не может преобразовать данные между этими типами. "

Базовый объект

public abstract class BaseEntity
{
    public string Id { get; set; }
    [Display(Name = "Created At")]
    public DateTimeOffset CreatedAt { get; set; }

    public BaseEntity()
    {
        Id = Guid.NewGuid().ToString();
        CreatedAt = DateTime.Now;
    }
}

Марка Модель

public class Brand : BaseEntity
{
    public string Name { get; set; }
}

Просмотр модели

public class ProductFormViewModel
{
    public Product Product { get; set; }
    public IEnumerable<Brand> Brands { get; set; }
}

Инвентарный контроллер

public class InventoryController : Controller
{
    private readonly IRepository<Product> _productContext;
    private readonly IRepository<Brand> _brandContext;
    private readonly IRepository<Source> _sourceContext;
    public InventoryController(IRepository<Product> productContext, IRepository<Brand> brandContext, 
        IRepository<Source> sourceContext)
    {
        _productContext = productContext;
        _sourceContext = sourceContext;
        _brandContext = brandContext;
    }
    // GET: Inventory
    public ActionResult Index()
    {
        List<Product> Products = _productContext.Collection().ToList();
        return View(Products);
    }

    public ActionResult Create()
    {
        ProductFormViewModel product = new ProductFormViewModel
        {
            Product = new Product(),
            Brands = _brandContext.Collection().ToList(),
            Sources = _sourceContext.Collection().ToList()
        };
        return View(product);
    }
    [HttpPost]
    public ActionResult Create(ProductFormViewModel vm)
    {
        if (!ModelState.IsValid)
            return View("Create", vm);
        else
        {
            Product product = new Product
            {
                Brand = vm.Product.Brand,
                BrandId = vm.Product.BrandId,
                Comments = vm.Product.Comments,
                Cost = vm.Product.Cost,
                DiscountPercent = vm.Product.DiscountPercent,
                ItemCode = vm.Product.ItemCode,
                Source = vm.Product.Source,
                SourceId = vm.Product.SourceId,
                SKU = vm.Product.SKU,
                UPC = vm.Product.UPC
            };

            _productContext.Insert(product);
            _productContext.Commit();
            return RedirectToAction("Index");
        }
    }
}

Просмотр

@model SuperStockpile.Core.ViewModels.ProductFormViewModel

@{
    ViewBag.Title = "Create";
}

<h2>Add New Product</h2>


@using (Html.BeginForm("Create","Inventory")) 
{
    @Html.AntiForgeryToken()
    
<div class="form-horizontal">
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.Product.SKU)
        @Html.EditorFor(model => model.Product.SKU, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Product.SKU)
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Product.UPC)
        @Html.EditorFor(model => model.Product.UPC, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Product.UPC)
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Product.ItemCode)
        @Html.EditorFor(model => model.Product.ItemCode, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Product.ItemCode)
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Product.Cost)
        @Html.EditorFor(model => model.Product.Cost, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Product.Cost)
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Product.DiscountPercent)
        @Html.EditorFor(model => model.Product.DiscountPercent, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Product.DiscountPercent)
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Product.Comments)
        @Html.EditorFor(model => model.Product.Comments, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Product.Comments)
    </div>
    <div class="form-group">
        @Html.LabelFor(model => model.Product.BrandId)
        @Html.DropDownListFor(model => model.Product.Brand, new SelectList(Model.Brands, "Id", "Name"),"Select Brand", new { @class = "form-control" })
        @Html.ValidationMessageFor(model => model.Product.BrandId)
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Save" class="btn btn-default" />
        </div>
    </div>
</div>
}

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

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

Я не уверен, как правильно привязать раскрывающийся список к моему представлению модели Brand property.Любая помощь или объяснение, почему это происходит, было бы замечательно!

Спасибо за поиск.

1 Ответ

1 голос
/ 03 апреля 2019

Не привязывайте к классу бренда в целом, привязывайте только к Brand.Id, позже в контроллере получите оставшиеся данные для бренда перед сохранением в базу данных.

@Html.DropDownListFor(model => model.Product.Brand.Id, new SelectList(Model.Brands, "Id", "Name"),"Select Brand", new { @class = "form-control" })
...