在MVC4中创建和编辑的视图相同

时间:2013-06-14 11:21:53

标签: asp.net-mvc-4

我们可以为创建和编辑操作创建一个剃刀视图吗?

如果是,我们如何实现这一目标?

7 个答案:

答案 0 :(得分:47)

我不推荐它。

这应该是一个相当长的答案,因为正常的MVC GET / POST工作流程的过程,请求和工作流程涉及很多事情。我将尝试用所需的最少信息回答您的问题,以及为什么我不建议使用相同的视图。

首先,为什么?

  1. 您无权控制可能有过度发布的观点;
  2. 没有灵活性;
  3. 不可重复使用的观点或部分;
  4. 难以维护视图(必须在两个操作上测试视图中的一个更改)。
  5. 我建议的方法是使用不同的操作/视图,但共享公共代码:

    正常创建两个视图。

    您将拥有重复的代码,但并非所有代码都相同,例如,您可能不希望在创建操作上发送ID,这与您的问题没有直接关系,但使用相同的视图意味着您也发送相同的数据,这是不推荐的,特别是对于过度发布或批量分配。有关质量分配here的更多信息(建筑方法就是我在这里使用的)。

    那么让我们从您将在控制器中收到的内容开始。 在这种情况下,我使用了继承,但这不是唯一的策略。

    绑定模型

    public class UpdateBindingModel : CreateBindingModel {
        // since we are not using the same binding model, 
        // we can have a "real" validation rules on our update binding and view.
        [Required]
        public int? Id {get;set;}
    }
    
    public class CreateBindingModel {
        // no id here prevent overposting.
        [Required]
        public string Name {get;set;}
        [Required]
        public int? CountryId {get;set;}
    }
    

    这将确保您发送到“创建”和“编辑”的数据是最不需要的,而不是其他任何内容。

    然后让我们看看将发送到View的View Models,对于这个例子,我将包含一个List,用于选择一些值,但不应该发布(列表)到控制器,只有选定的值

    查看模型

    public class CreateViewModel : CreateBindingModel {
        public IEnumerable<SelectListItem> CountryList {get;set;}
    }
    
    public class UpdateViewModel : UpdateBindingModel {
        public IEnumerable<SelectListItem> CountryList {get;set;}
    }
    

    正如您所看到的,这为您提供了很大的灵活性,但仍然有一些重复的代码(两个视图的视图模型所需的额外信息),可以通过多种方式(根据需求/上下文)进行缓解:

    1. 执行操作以检索公共数据并使用@Html.Action("GetCountryList");
    2. 使用相同的View Model#{1}}并在视图中丢弃额外的CreateUpdateViewModel属性,但仍然在POST上发布相应的模型。
    3. 将绑定模型作为属性,并在特定视图中选择一个或另一个。 (更好地使用UpdateBindingModel而不是部分,因此Model Binder无需对代码进行其他更改即可使用
    4. 控制器操作如下所示:

      <强>控制器

      @Html.EditorFor

      您的观点:

      <强>视图

      [HttpGet]
      public ActionResult Create(){
          ViewData.Model = new CreateViewModel();
          return View();
      }
      
      [HttpPost]
      public RedirectToRouteResult Create(CreateBindingModel binding) {
          // check valid model state and create data
          return RedirectToAction("Index");
      }
      
      [HttpGet]
      public ActionResult Update(int id) {
          var objectToEdit = service.GetObjectToEdit(id);
          ViewData.Model = new UpdateViewModel(objectToEdit);
          return View();
      }
      
      [HttpPost]
      public RedirectToRouteResult Update(UpdateBindingModel binding) {
          // check valid model state and update data
          return RedirectToAction("Index");
      }
      

      注意:代码不完整,在大多数情况下都没有使用帮助程序,以简洁明了。不要复制粘贴:D

答案 1 :(得分:42)

当然可以。

在帖子上,检查您的控制器是否主键值为0然后插入,否则更新。

“创建和编辑”视图应该相同。

请记住包括:

@Html.HiddenFor(model=>model.ID)

在你看来

例如:

型号:

public class DescriptionModel
{
    [Key]
    public int ID { get; set; }

    public string Description { get; set; }
}

CreateEdit.cshtml:

@model DescriptionModel

@using (Html.BeginForm("CreateEdit"))
{
    @Html.HiddenFor(model=> model.ID)
    @Html.EditorFor(model=> model.Description)
    <input type="submit" value='Submit' />
}

DescriptionModel控制器:

public ActionResult Create()
{
    return View("CreateEdit", new DescriptionModel());
}
public ActionResult Edit(int id)
{
    return View("CreateEdit", db.DescriptionModels.Find(id));
}

// Submit and add or update database
[HttpPost]
public ActionResult CreateEdit(DescriptionModel model)
{
    if (ModelState.IsValid)
    {
       // No id so we add it to database
       if (model.ID <= 0)
       {
           db.DescriptionModels.Add(model);
       }
       // Has Id, therefore it's in database so we update
       else
       {
           db.Entry(model).State = EntityState.Modified;
       }
       db.SaveChanges();
       return RedirectToAction("Index");
    }

    return View(model);
}

答案 2 :(得分:2)

我不推荐这种方法,但您可以将主窗体从部分

加载到两个视图中

答案 3 :(得分:2)

使用相同的模型,绝对可以为创建和编辑操作共享视图。 然而,我强烈建议您考虑两次。在许多情况下,您将需要具有不同的编辑操作视图(例如,隐藏一些不应该可编辑的输入)以及模型可能略有不同,尽管它可能共享一些(或大多数)值。这些差异将导致视图中的某些条件,检查您是否正在创建或编辑 - 这可能会使代码混乱。 结论:在决定是否拥有共享视图之前,请尝试考虑编辑屏幕与创建屏幕的差异程度,然后您可以决定。

答案 4 :(得分:1)

你当然可以,但通常这是我会尽量避免的。如果创建和编辑操作几乎相同,那么最终会复制控制器中的大量代码。通常在这种情况下,我的“添加”控制器上只有几个字段,然后一旦添加了项目,我就会将用户重定向到编辑页面,在那里他们可以填写其余的信息。

答案 5 :(得分:0)

[HttpGet]
 public ActionResult myFun(int id = 0)
        {
            MyClass cls = new MyClass();
            if (id == 0)
            {
                //Insert mode ... no data will be shown to textboxes , when primary key ie. id=0
               //Display whole data
            }
            else
            {
                //Update mode... if id is not 0 ,data will be shown to textboxes
            }

            return View(cls);
        }

答案 6 :(得分:-1)

所以,让我们考虑一下。如果MVC规定代码/视图/等重复,那一定是一个缺陷吗?作为程序员,我永远都不想重复任何努力