Asp.net mvc 4 MVC4中创建和编辑的视图相同

Asp.net mvc 4 MVC4中创建和编辑的视图相同,asp.net-mvc-4,Asp.net Mvc 4,我们能为创建和编辑操作提供一个razor视图吗 如果是,我们如何实现这一点?我不推荐这种方法,但您可以将主表单从部分加载到两个视图中,当然可以 在post中,在控制器中检查主键是否具有值0,然后插入,否则更新 “创建”和“编辑”的视图应相同 请记住包括: @Html.HiddenFor(model=>model.ID) 在你看来 例如: 型号: public class DescriptionModel { [Key] public int ID { get; set;

我们能为创建和编辑操作提供一个razor视图吗


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

我不推荐这种方法,但您可以将主表单从部分加载到两个视图中,当然可以

在post中,在控制器中检查主键是否具有值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' />
}
@模型描述模型
@使用(Html.BeginForm(“CreateEdit”))
{
@Html.HiddenFor(model=>model.ID)
@EditorFor(model=>model.Description)
}
描述模型控制器:

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);
}
public ActionResult Create()
{
返回视图(“CreateEdit”,new DescriptionModel());
}
公共操作结果编辑(int id)
{
返回视图(“CreateEdit”,db.DescriptionModels.Find(id));
}
//提交并添加或更新数据库
[HttpPost]
公共操作结果CreateEdit(DescriptionModel模型)
{
if(ModelState.IsValid)
{
//没有id,所以我们将其添加到数据库中

如果(model.ID您当然可以,但通常我会尽量避免这种情况。如果创建和编辑操作实际上相同,那么您最终会在控制器中复制大量代码。通常在这种情况下,我的“添加”控制器上只有几个字段,然后在添加项目后,我将用户重定向到编辑pa他们可以在ge上填写其余的信息。

我不推荐这样做

[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);
        }
这应该是一个相当长的答案,因为在普通MVC GET/POST工作流的过程、请求和工作流中涉及很多事情。我将尝试用所需的最少信息回答您的问题,以及为什么我不建议使用相同的视图

首先,为什么

  • 您无法控制视图,这可能会影响发布
  • 没有灵活性
  • 不可重复使用的视图或零件
  • 难以维护视图(视图中的一个更改必须在两个操作上进行测试)
  • 我建议的方法是使用不同的操作/视图,但共享相同的代码:

    按常规创建两个视图

    您将有重复的代码,但并非所有代码都相同,例如,您可能不想在创建操作上发送ID,这与您的问题没有直接关系,但使用相同的视图意味着您也发送相同的数据,不建议这样做,尤其是对于过度发布或批量分配。有关批量分配的详细信息ment(我在这里使用的是一种体系结构方法)

    那么,让我们从控制器中接收到的内容开始。 在本例中,我使用了继承,但这不是唯一的策略

    绑定模型

    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;}
    }
    
    public class CreateViewModel : CreateBindingModel {
        public IEnumerable<SelectListItem> CountryList {get;set;}
    }
    
    public class UpdateViewModel : UpdateBindingModel {
        public IEnumerable<SelectListItem> CountryList {get;set;}
    }
    
    Update.cshtml
    <form action="Update">
        @Html.HiddenFor(Model.Id);
        @Html.Partial("EditFieldsPartial")
        <button>delete</button> // no delete button on create.
        <button>create new</button> // you can have a create new instead of update.
    </form>
    
    Create.cshtml
    <form action="Create">
        @Html.Partial("EditFieldsPartial")
    </form>
    
    这将确保您发送给创建和编辑的数据是所需的最小数据,而不是其他数据

    然后,让我们看看将发送到视图的视图模型,在本例中,我将包括一个列表,该列表将用于选择一些值,但不应发布(列表)到控制器,仅显示选定的值

    查看模型

    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;}
    }
    
    public class CreateViewModel : CreateBindingModel {
        public IEnumerable<SelectListItem> CountryList {get;set;}
    }
    
    public class UpdateViewModel : UpdateBindingModel {
        public IEnumerable<SelectListItem> CountryList {get;set;}
    }
    
    Update.cshtml
    <form action="Update">
        @Html.HiddenFor(Model.Id);
        @Html.Partial("EditFieldsPartial")
        <button>delete</button> // no delete button on create.
        <button>create new</button> // you can have a create new instead of update.
    </form>
    
    Create.cshtml
    <form action="Create">
        @Html.Partial("EditFieldsPartial")
    </form>
    
    以及你的意见:

    视图

    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;}
    }
    
    public class CreateViewModel : CreateBindingModel {
        public IEnumerable<SelectListItem> CountryList {get;set;}
    }
    
    public class UpdateViewModel : UpdateBindingModel {
        public IEnumerable<SelectListItem> CountryList {get;set;}
    }
    
    Update.cshtml
    <form action="Update">
        @Html.HiddenFor(Model.Id);
        @Html.Partial("EditFieldsPartial")
        <button>delete</button> // no delete button on create.
        <button>create new</button> // you can have a create new instead of update.
    </form>
    
    Create.cshtml
    <form action="Create">
        @Html.Partial("EditFieldsPartial")
    </form>
    
    Update.cshtml
    @Html.HiddenFor(Model.Id);
    @Html.Partial(“EditFieldSpatial”)
    删除//创建时没有删除按钮。
    create new//您可以使用create new而不是update。
    Create.cshtml
    @Html.Partial(“EditFieldSpatial”)
    

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

    使用相同的模型,创建和编辑操作肯定可以共享视图。但是,我强烈建议您三思。在许多情况下,您需要使用不同的视图进行编辑选项(例如,隐藏一些不应编辑的输入)以及模型可能略有不同,但可能共享一些(或大部分)值。这些差异将导致视图中出现某些条件,检查您是否正在创建或编辑-这可能会使代码混乱。
    结论:在决定是否拥有共享视图之前,试着想想编辑屏幕和创建屏幕的区别有多大,然后你可以决定。

    所以,让我们想想。如果MVC规定代码/视图/等必须复制,那么这肯定是一个缺陷。作为一名程序员,我永远不想重复任何工作呃,不管其他什么。

    我相信这种方法很容易受到套印攻击。例如,黑客可以导航到他们记录的编辑页面,修改隐藏字段
    DescriptionModel.ID
    的值,以指向他们不应该能够访问的另一条记录。当他们发布表单时,它将修改其他记录而不是他们自己的记录。概述了解决此安全问题的另一种方法。@如果他可以创建一些其他Id作为guid,因为通过presentantion公开数据库Id不是一种好做法。我认为你可以使用AddOrUpdate,然后你甚至不需要检查,对吗,
    AddOrUpdate
    方法用于在迁移期间运行种子时防止重复。在生产环境中使用该方法可能会导致意外/不期望的结果。@如果您可以使用一个简单的
    if
    语句来解决安全问题。类似于(伪代码)
    如果Model.User!=currentUser,则抛出新的禁止异常()
    Id,而不是维护两个相对相同的表单。您的
    不应该更新(int-Id)吗
    控制器中的函数使用UpdateBindingModel而不是CreateBindingModel来获得Id?@brianestey很好的捕获。修复了它,但您应该使用ViewModels而不是bindingmodel。检查更新的答案。@BartCalixto在
    创建
    操作中,如果
    模型状态