繁体   English   中英

C# MVC HttpPost 失败 – ViewModel ModelState 问题(来自类型“System.String”的参数转换...)

[英]C# MVC HttpPost Failed – ViewModel ModelState Issue (The parameter conversion from type 'System.String'…)

提交表单时会出现此问题,触发 HttpPost 返回控制器。 ViewModel 已部分填充,但主要实体(“StockItem”)为空。 ModelState 有以下错误:

[System.InvalidOperationException] = {"The parameter conversion from type 'System.String' to type 'RaRApps.Domain.Entities.StockItem' failed because no type converter can convert between these types."}

这是一些背景:

这是“StockItem”对象定义。 它包括与其他 4 个对象的关系(其中一个被引用 3 次):

public class StockItem  
{  
    public int id { get; set; }  
    public string title { get; set; }  

    public virtual StockType stockType {get;set;}  
    public virtual Category category {get;set;}  
    public virtual Supplier supplier {get;set;}  
    public virtual Unit purchUnit { get; set; }  
    public virtual Unit countUnit { get; set; }  
    public virtual Unit useUnit { get; set; }  
}  

上下文设置如下,并明确定义了关系:

public class EFDbContext : DbContext  
{  
    public DbSet<Category> Categories { get; set; }  
    public DbSet<Supplier> Suppliers { get; set; }  
    public DbSet<Unit> Units { get; set; }  


    protected override void OnModelCreating(DbModelBuilder modelBuilder)  
    {  
        modelBuilder.Entity<Category>().ToTable("categories");  
        modelBuilder.Entity<StockItem>().ToTable("stock_items");  
        modelBuilder.Entity<Supplier>().ToTable("suppliers");  
        modelBuilder.Entity<Unit>().ToTable("units");  

        modelBuilder.Entity<StockItem>().HasRequired(s => s.purchUnit)  
            .WithMany(u => u.purchaseStockItems)  
            .Map(m => m.MapKey("purch_unit_id"));  

        modelBuilder.Entity<StockItem>().HasRequired(s => s.countUnit)  
            .WithMany(u => u.countStockItems)  
            .Map(m => m.MapKey("count_unit_id"));  

        modelBuilder.Entity<StockItem>().HasRequired(s => s.useUnit)  
            .WithMany(u => u.useStockItems)  
            .Map(m => m.MapKey("use_unit_id"));  

        modelBuilder.Entity<StockItem>().HasRequired(s => s.supplier)  
            .WithMany(u => u.stockItems)  
            .Map(m => m.MapKey("supplier_id"));  

        modelBuilder.Entity<StockItem>().HasRequired(c => c.category)  
            .WithMany(s => s.stockItems)  
            .Map(m => m.MapKey("category_id"));  

    }  
}  

ViewModel 用于传递: + “StockItem”对象 + DropDownLists 的值 + 选择 DropDownList 值

public class EditStockItemModel  
{  
    public StockItem stockItem { get; set; }  

    public SelectList supplierList { get; set; }  
    public int selectedSupplier { get; set; }  

    public SelectList categoryList { get; set; }  
    public int selectedCategory { get; set; }  

    public SelectList purchUnitList { get; set; }  
    public int selectedPurchUnit { get; set; }  

    public SelectList countUnitList { get; set; }  
    public int selectedCountUnit { get; set; }  

    public SelectList useUnitList { get; set; }  
    public int selectedUseUnit { get; set; }  
}  

“StockItem”控制器在调用“编辑”视图之前填充视图模型

    public ActionResult Edit(int stockItem_id)  
    {  
        StockItem Item = this.stockItemRepo.SiteStockItems().FirstOrDefault(p => p.id == stockItem_id);  
        EditStockItemModel model = new EditStockItemModel();  

        model.stockItem = Item;  
        model.selectedCategory = Item.category.id;  
        model.selectedSupplier = Item.supplier.id;  
        model.selectedPurchUnit = Item.purchUnit.id;  
        model.selectedCountUnit = Item.countUnit.id;  
        model.selectedUseUnit = Item.useUnit.id;  

        using (IKernel kernel = new StandardKernel())  
        {  
            kernel.Bind<ICategoryRepository>().To<EFCategoryRepository>();  
            model.categoryList = new SelectList(kernel.Get<ICategoryRepository>().SiteStockCategories(site_id).Where(s => s.active == 1), "id", "title");  

            kernel.Bind<ISupplierRepository>().To<EFSupplierRepository>();  
            model.supplierList = new SelectList(kernel.Get<ISupplierRepository>().SiteSuppliers(site_id).Where(s => s.active == 1), "id", "title");  

            kernel.Bind<IUnitRepository>().To<EFUnitRepository>();  
            model.purchUnitList = new SelectList(kernel.Get<IUnitRepository>().SiteUnits(site_id).Where(u => u.active == 1), "id", "title");  
            model.countUnitList = new SelectList(kernel.Get<IUnitRepository>().SiteUnits(site_id).Where(u => u.active == 1), "id", "title");  
            model.useUnitList = new SelectList(kernel.Get<IUnitRepository>().SiteUnits(site_id).Where(u => u.active == 1), "id", "title");  
        }  

        return View(model);  
    }  

当提交视图表单时,视图模型被传递回“StockItem”控制器。 但是,“StockItem”对象是空的。 ModelState 显示一个错误,提示无法生成“StockItem”。

    [HttpPost]  
    public ActionResult Edit(EditStockItemModel model)  
    {  
        if (ModelState.IsValid)  
        {  
            stockItemRepo.SaveStockItem(model.stockItem, model.selectedCategory, model.selectedSupplier, model.selectedPurchUnit, model.selectedCountUnit, model.selectedUseUnit);  
        }  
        return RedirectToAction("List");  
    }  

任何有关如何纠正此问题的建议将不胜感激。

根据要求,这是查看代码。 我将 SelectLists 更改为来自 ViewBag 以简化发布的模型。

@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>


    @Html.HiddenFor(model => model.stockItem, new { id = "hdnID"})

    <div class="editor-label">
        @Html.LabelFor(model => model.stockItem.title)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.stockItem.title)
        @Html.ValidationMessageFor(model => model.stockItem.title)
    </div>


            <div class="editor-label">
                @Html.LabelFor(model => model.stockItem.category)
            </div>
            <div class="editor-field">
                @Html.DropDownListFor(model => model.selectedCategory, (SelectList)ViewBag.categoryList)
            </div>

            <div class="editor-label">
                @Html.LabelFor(model => model.stockItem.supplier)
            </div>
            <div class="editor-field">
                @Html.DropDownListFor(model => model.selectedSupplier, (SelectList)ViewBag.supplierList)
            </div>

            <div class="editor-label">
                @Html.LabelFor(model => model.stockItem.purchUnit)
            </div>
            <div class="editor-field">
                @Html.DropDownListFor(model => model.selectedPurchUnit, (SelectList)ViewBag.purchUnitList)
            </div>

            <div class="editor-label">
                @Html.LabelFor(model => model.stockItem.countUnit)
            </div>
            <div class="editor-field">
                @Html.DropDownListFor(model => model.selectedCountUnit, (SelectList)ViewBag.countUnitList)
            </div>

            <div class="editor-label">
                @Html.LabelFor(model => model.stockItem.useUnit)
            </div>
            <div class="editor-field">
                @Html.DropDownListFor(model => model.selectedUseUnit, (SelectList)ViewBag.useUnitList)
            </div>


    <div style="text-align:center;">
        <input type="submit" value="Save" data-role="button" data-inline="true" data-icon="check" />
    </div>
</fieldset>
}

我发现了问题! 视图有一个小错误。 以下标记没有指定字段。

@Html.HiddenFor(model => model.stockItem, new { id = "hdnID"})

当我包含该字段时,它会起作用,如下所示:

@Html.HiddenFor(model => model.stockItem.id, new { id = "hdnID"})

块引用

我发现了问题! 视图有一个小错误。 以下标记没有指定字段。

@Html.HiddenFor(model => model.stockItem, new { id = "hdnID"}) 当我包含字段时它起作用,如下所示:

@Html.HiddenFor(model => model.stockItem.id, new { id = "hdnID"})

它的魔力

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM