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

时间:2014-10-04 11:16:26

标签: c# asp.net-mvc razor

  • .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" } })

然后 New.cshtml 如下:

@model EnergyMission.Country.Dtos.GetNewCountryOutput

@{
    ViewBag.Title = "New Country";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@Html.Partial("_AddEditPartial", new ViewDataDictionary { { "ActionName", "Create" } })

从上面注意到:

  1. 每个人都有不同的模型,即 GetCountryOutput GetNewCountryOutput 。这两者都具有相同的属性。目前,由于其他原因,他们不能成为同一个班级。
  2. 我传递了操作名称,以便我可以在局部视图中的 Html.BeginForm 中使用它
  3. 我仍然需要弄清楚如何将模型类型传递给局部视图
  4. _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. 是否有更简单的方法来共享我在上面做的添加/编辑操作的公共数据输入布局?
    2. 如果我按照所描述的方法进行操作:

      1. 将模型类型传递给局部视图。是这样的:
      2. _

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

        然后在_AddEdit.cshtml

        _

        @model  typeof(@ViewData["ModelTypeName"])
        
        1. 以下为何无效:
        2. _

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

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

2 个答案:

答案 0 :(得分:1)

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

控制器和存储库的简化示例(使用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();
    }

}

答案 1 :(得分:0)

3.答案是3. html.beginform需要一个字符串作为它的第一个参数,并且正在使用ViewData这是一个

Dictionary<string, object> 

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

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

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