使用相同的局部视图进行编辑和新建操作

本文关键字:编辑 新建 操作 视图 局部 | 更新日期: 2023-09-27 18:25:41

  • .NET 4.51,MVC 5

我有一个视图Edit.cshtml如下:

@model EnergyMission.Country.Dtos.GetCountryOutput
@{
    ViewBag.Title = "Edit Country";
    Layout = "~/Views/Shared/_Layout.cshtml";
}             
@Html.Partial("_AddEditPartial", new ViewDataDictionary { { "ActionName", "Edit" } })

然后新建.cshtml如下:

@model EnergyMission.Country.Dtos.GetNewCountryOutput
@{
    ViewBag.Title = "New Country";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@Html.Partial("_AddEditPartial", new ViewDataDictionary { { "ActionName", "Create" } })

注意:

  1. 每个都有一个不同的模型,即GetCountryOutputGetNewCountryOutput这两者都具有相同的属性。目前,由于其他原因,它们不能成为同一类
  2. 我传递操作名称,以便在部分视图中的Html.BeginForm中使用它
  3. 我仍然需要弄清楚如何将模型类型传递给局部视图

_AddEditPartial.cshtml如下所示:

@model  EnergyMission.Country.Dtos.GetCountryOutput
<h3>@ViewData["ActionName"]</h3>
@using (Html.BeginForm(@ViewData["ActionName"], "Countries"))
{
    @Html.AntiForgeryToken()
    <div class="form-horizontal">
        <h4>CountryTableModel</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.AbbreviationCode, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.AbbreviationCode, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.AbbreviationCode, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.InternationalCountryDialCode, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.InternationalCountryDialCode, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.InternationalCountryDialCode, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>
    </div>
}

我的问题如下:

  1. 有没有一种更简单的方法可以共享我上面正在做的添加/编辑操作的通用数据条目布局

如果我要遵循描述的方法,我该如何:

  1. 将模型类型传递给局部视图。是不是有点像:

_

@Html.Partial("_AddEditPartial", new ViewDataDictionary { { "ActionName", "Create" }, {"ModelTypeName", "EnergyMission.Country.Dtos.GetCountryOutput"} })

然后在_AddEdit.cshtml 中

_

@model  typeof(@ViewData["ModelTypeName"])
  1. 为什么以下内容无效:

_

@using (Html.BeginForm(ViewData["ActionName"], "Countries"))

因为这会给我一个编译时错误。

使用相同的局部视图进行编辑和新建操作

创建单个视图,然后使用控制器指向单个视图,并使用存储库在Save方法中相应地插入/更新。但是,请注意,在下面的示例中,您需要确保模型是相同的——基于应该消除重复的原则。如果这不可能,请考虑在视图中使用动态模型或使用ViewModel,您可以相应地映射属性(无论如何,我不想让答案过于复杂,因为我希望这能提供您需要的解决方案-在这里或那里进行一些重构)。

控制器和存储库的简化示例(使用视图模型)。。。。

public class ProductController : Controller
{
   private IProductRepository _repository;
   public ProductController(IProductRepository productsRepository)
   {
       this._repository = productsRepository;
   }
    public ViewResult Edit(int productID)
    {
        ProductEditViewModel model = new ProductEditViewModel
        {
            Product = this._repository.Products.Where(m => m.ProductID == productID).FirstOrDefault()
        };
        return View(model);
    }
    [HttpPost]
    public ActionResult Edit(int productId)
    {
        ProductEditViewModel model = new ProductEditViewModel
        {
            Product = _repository.Products.First(m => m.ProductID == productId)
        };
        TryUpdateModel(model);
        if (ModelState.IsValid)
        {
            _repository.Save(model.Product);
            return RedirectToAction("Index");
        }
        else
        {
            return View(model);
        }
    }
    public ViewResult Create()
    {
        return View("Edit", new Product());
    }
    [HttpPost]
    public ActionResult Create(Product product)
    {
        return Edit(product.ProductID);
     }
 }

存储库。。。。

public class SqlProductRepository : IProductRepository
{
     private MyDataContext db;
     private Table<Product> _productsTable; 
    public IQueryable<Product> Products
    {
        get { return _productsTable; }
    }
    public void Save(Product product)
    {
        if (product.ProductID == 0)
        {
            _productsTable.InsertOnSubmit(product);
        }
        else if (_productsTable.GetOriginalEntityState(product) == null)
        {
            _productsTable.Attach(product);
            _productsTable.Context.Refresh(RefreshMode.KeepCurrentValues, product);
        }
        _productsTable.Context.SubmitChanges();
    }

}

答案是3。是html.beginform需要一个字符串作为它的第一个参数,并且当您使用作为的ViewData时

Dictionary<string, object> 

您需要将您的价值转换为字符串:

@using (Html.BeginForm(ViewData["ActionName"] as string, "Countries"))

对于1。您可以尝试从基类派生两个dto类,并将该类设置为添加和编辑视图的模型类型