微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MVC 编辑和发送带有部分视图的模型视图

如何解决MVC 编辑和发送带有部分视图的模型视图

我正在一个带有复杂模型的视图的项目中工作(为简单起见,我举了这个例子):

public class Person
{
    public string Name { get; set; }
    public string LastName { get; set; }
    public string Data3 { get; set; }
    public string Data4 { get; set; }
    public List<Movie> Movies { get; set; }
}

public class Movie
{
    public string Name { get; set; }
    public double Cost { get; set; }
    public double Quantity { get; set; }
}

我有一个主视图人,有两个部分视图“_Movies”和“_Books”

@Html.Partial("_Movies",Model.Movies)

@Html.Partial("_Books",Model.Books)

这些局部视图中的每一个都有一个添加按钮”,它会打开一个弹出窗口,请求以下数据:

这个想法是,当我插入这些数据时,它会显示一个包含电影列表和输入数据的网格。能够编辑或删除这些数据。

当我按下底部的“全部保存”按钮时,它会将所有模型数据发送到控制器。

但我不知道如何将模型数据一起发送。我很绝望。

如何编辑和刷新 Partial Views 的数据并获取它们的数据以将完整模型发送到控制器?

enter image description here

还有我的代码...

主控制器:

public class PersonController : Controller
{
    // GET: Person
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Create()
    {
        ViewBag.Movies = new SelectList(new List<SelectListItem> {
            new SelectListItem { Text = "Lord of the rings",Value = "Lord of the rings"},new SelectListItem { Text = "Inception",Value = "Inception"}
        },"Value","Text");

        return View(new Person());
    }

    [HttpPost]
    public ActionResult Create(Person person)
    {
        try
        {
            // Todo: Add insert logic here

            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }

    [ChildActionOnly]
    public ActionResult RefreshMovies(List<Movie> movies)
    {
        ViewBag.Movies = new SelectList(new List<SelectListItem> {
            new SelectListItem { Text = "Lord of the rings","Text");

        return PartialView("~/Views/Person/_Movies.cshtml",movies ?? new List<Movie>());
    }
}

主视图:

@model MisPruebasMVC.Models.Person

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

<h2>General Data</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <hr />
        @Html.ValidationSummary(true,"",new { @class = "text-danger" })
        <div class="form-group">
            <div class="col-md-4">
                @Html.LabelFor(model => model.Name,htmlAttributes: new { @class = "control-label" })
                @Html.EditorFor(model => model.Name,new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name,new { @class = "text-danger" })
            </div>

            <div class="col-md-4">
                @Html.LabelFor(model => model.LastName,htmlAttributes: new { @class = "control-label" })
                @Html.EditorFor(model => model.LastName,new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.LastName,new { @class = "text-danger" })
            </div>
        </div>


        <div class="form-group">
            <div class="col-md-4">
                @Html.LabelFor(model => model.Data3,htmlAttributes: new { @class = "control-label" })
                @Html.EditorFor(model => model.Data3,new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Data3,new { @class = "text-danger" })
            </div>

            <div class="col-md-4">
                @Html.LabelFor(model => model.Data4,htmlAttributes: new { @class = "control-label" })
                @Html.EditorFor(model => model.Data4,new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Data4,new { @class = "text-danger" })
            </div>
        </div>


        @Html.Partial("_Movies",Model.Movies ?? new List<MisPruebasMVC.Models.Movie>())

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

部分视图_Movies.cshtml:

@model IEnumerable<MisPruebasMVC.Models.Movie>


<h2>Movies</h2>

<div class="form-group">
    <button id="addisPCost" type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">
        Add movie
    </button>
</div>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h3 class="modal-title" id="exampleModalLabel">New Movie</h3>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                </button>
            </div>

            <div class="modal-body">
                @{
                    var newMovie = new MisPruebasMVC.Models.Movie();
                }

                <div class="form-group">
                    @Html.LabelFor(m => newMovie.Name,"ISP *:",htmlAttributes: new { @class = "control-label col-md-3" })
                    <div class="col-md-9">
                        @Html.DropDownList("Id_ISP",new SelectList(ViewBag.Movies,"Text"),"Select a movie",new { @class = "form-control",@id = "IdisP" })
                        @Html.ValidationMessageFor(m => newMovie.Name,new { @class = "text-danger" })
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(m => newMovie.Cost,"Cost:",htmlAttributes: new { @class = "control-label col-md-3" })
                    <div class="col-md-9">
                        @Html.EditorFor(m => newMovie.Cost,new { htmlAttributes = new { @class = "form-control",@id = "Cost" } })
                        @Html.ValidationMessageFor(m => newMovie.Cost,new { @class = "text-danger" })
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(m => newMovie.Quantity,"Quantity:",htmlAttributes: new { @class = "control-label col-md-3" })
                    <div class="col-md-9">
                        @Html.EditorFor(m => newMovie.Quantity,@id = "MaximoDiario" } })
                        @Html.ValidationMessageFor(m => newMovie.Quantity,new { @class = "text-danger" })
                    </div>
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Cerrar</button>
                <button type="button" class="btn btn-primary" id="saveConfiguracionISP">Aceptar</button>
            </div>
        </div>
    </div>
</div>

<table class="table">
    <tr>
        <th>
            @Html.displayNameFor(model => model.Name)
        </th>
        <th>
            @Html.displayNameFor(model => model.Cost)
        </th>
        <th>
            @Html.displayNameFor(model => model.Quantity)
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.displayFor(modelItem => item.Name)
            </td>
            <td>
                @Html.displayFor(modelItem => item.Cost)
            </td>
            <td>
                @Html.displayFor(modelItem => item.Quantity)
            </td>
        </tr>
    }

</table>

_Books Partial View 与 _Movies Partial View 相同。

我试图将部分放在与主目录相同的目录中并通过

调用它们
@Html.Partial("_Movies",Model.Movies ?? new List<MisPruebasMVC.Models.Movie>())

我也试过

@Html.Action("RefreshMovies",Model.Movies)

调用此操作

[ChildActionOnly]
public ActionResult RefreshMovies(List<Movie> movies)
{
    ViewBag.Movies = new SelectList(new List<SelectListItem> {
        new SelectListItem { Text = "Lord of the rings",Value = "Inception"}
    },"Text");

    return PartialView("~/Views/Person/_Movies.cshtml",movies ?? new List<Movie>());
}

即使我尝试将它们移动到共享文件夹内的 EditorTemplates 文件夹,调用它们:

@Html.EditorFor(m=> m.Movies,"_Movies") @Html.EditorFor(m=> m.Books,"_Books")

但是我不知道如何将部分视图中的电影和书籍列表添加到父视图模型中,然后通过在 BeginForm 中提交将它们发送到控制器。

有什么想法吗?

解决方法

我已经实现将 MoviesBooks 属性中的局部视图的数据发送到控制器。

就我所见,视图只有在从控制器接收数据时才获取模型,然后将其解释为 HTML 并且仅将表单数据发送到控制器,我已解决如下:

>

对于 Person 实体,我添加了字符串类型的属性 MoviesRequestBooksRequest。在这里,我将收到两个 JSON 格式的数组,我将分别将它们解析为 MoviesBooks 属性,留下类 Person 如下:

public class Person
{
    public string Name { get; set; }
    public string LastName { get; set; }
    public string Data3 { get; set; }
    public string Data4 { get; set; }
    public List<Movie> Movies { get; set; }
    public List<Book> Books { get; set; }
    public string MoviesRequest { get; set; }
    public string BooksRequest { get; set; }
}

另一方面,在父视图中,我添加了两个引用这两个新属性的隐藏字段:

@Html.HiddenFor(m=> m.MoviesRequest,new { id = "hiddenMovies" })
@Html.HiddenFor(m=> m.BooksRequest,new { id = "hiddenBooks" })

在局部视图 _Books 中,我在 javascript 中有一个全局变量 books,我在 document.ready 中设置如下:

books = @Html.Raw(Json.Encode(Model));

并且每次我修改书籍数组时,我都会更新隐藏字段,并对其进行分配:

$("#hiddenBooks").val(JSON.stringify(books));

同一个表单局部视图_Movies

然后,在表单帖子中,在控制器中,我所做的就是以这种方式将它们解析为它们的原始属性:

[HttpPost]
public ActionResult Create(Person person)
{
    try
    {
        person.Books = JsonConvert.DeserializeObject<List<Books>>(person.BooksRequest);
        person.Movies = JsonConvert.DeserializeObject<List<Movies>>(person.MoviesRequest);
        
        // TODO: Add insert logic here

        return RedirectToAction("Index");
    }
    catch
    {
        return View();
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。