MVC ASP.Net:列表未正确提取

时间:2019-01-15 21:24:58

标签: c# asp.net-mvc razor t4mvc

我一直在尝试向使用ASP.Net和Razor中的T4MVC的现有Web项目添加新页面。除了一个错误,一切都运行顺利:当我提交表单时,viewmodel中的列表为null,好像无法使用数据创建它一样。

我尝试过更改一些名称,尝试过删除和重写所有内容,并尝试禁用验证程序,以为这会导致问题,但无济于事。我也尝试过使用“ T4MVC.tt”文件重新生成所有内容。即便如此,该功能基本上还是从另一个页面复制粘贴而来的,该页面具有非常相似的功能,但它的作用却很吸引人(因此HTML中的“挑剔”类)。

我发现它最有可能与“ @ Html.HiddenIndexerInputForModel()”如何生成供MVC查找的隐藏索引字段有关,因为其值始终为“ 0”,但即使在编辑时也是如此手动使它看起来不错,我得到相同的结果。

任何指针将不胜感激。我一直认为这是一个模型绑定错误,因为我使用的是默认绑定程序,但是据我所知,整个项目都依赖于默认绑定程序并且可以正常工作。

这是控制器,视图模型和视图(创建并接受容器)类。

控制器:

public partial class ContainerReceptionController : MvcController
{
    private readonly IDataTypeService _dataTypeService;
    private readonly IHttpContextService _httpContext;
    private readonly IEntityRepository<TubPicking> _tubPickingRepository;
    private readonly IEntityRepository<Image> _imageRepository;
    private readonly IEntityRepository<Company> _companyRepository;
    private readonly IContainerServices _containerService;
    private readonly IEntityRepository<Client> _clientRepository;
    private readonly IEntityRepository<Emplacement> _emplacementRepository;

    public ContainerReceptionController(IProviderServices provider, IHttpContextService httpContext)
    {
        _httpContext = httpContext;
        _dataTypeService = provider.GetDataTypeService();
        _tubPickingRepository = provider.GetTubPickingRepository();
        _imageRepository = provider.GetImageRepository();
        _containerService = provider.GetContainerServices();
        _companyRepository = provider.GetCompanyRepository();
        _clientRepository = provider.GetClientRepository();
        _emplacementRepository = provider.GetEmplacementRepository();
    }

    public virtual ActionResult Create()
    {
        int ownerId = _httpContext.GetUserOwnerId();

        string propertyName = "Owner.Id";
        string orderBy = "Id";
        string orderType = "ASC";

        List<Client> clients = _clientRepository.GetByProperty(propertyName, ownerId.ToString(), orderBy + " " + orderType).ToList();

        //Create a view model for the view
        ContainerReceptionViewModel createViewModel = new ContainerReceptionViewModel
        {
            OwnerId = ownerId,
            PickingId = 0,
            ReceivedContainers = new List<ContainerCreateViewModel>(),
            Clients = new SelectList(clients, "ID", "Name")
        };

        return View(createViewModel);
    }

    [HttpPost]
    public virtual ActionResult Create(ContainerReceptionViewModel viewModel)
    {
        int ownerId = _httpContext.GetUserOwnerId();

        // First, add all the containers in the database
        foreach (ContainerCreateViewModel item in viewModel.ReceivedContainers)
        {
            // Database operations here
        }

        this.Flash("alert alert-success", UiText.Account.Validation.CREATE_ACCOUNT_SUCCESS);

        return RedirectToAction(MVC.Container.Index());
    }

    // Used in the view to generate new containers
    public virtual PartialViewResult AddOperation(string id)
    {
        int ownerId = _httpContext.GetUserOwnerId();

        //Create data lists with a default value
        List<DataType> containerTypes = new DataType() { Id = -1, Display = UiText.Container.SELECT_CONTAINER_TYPE }.AsList<DataType>();
        List<DataType> materialTypes = new DataType() { Id = -1, Display = UiText.TubPicking.SELECT_MATERIAL_TYPE }.AsList<DataType>();
        List<Emplacement> emplacementTypes = new Emplacement() { Id = -1 }.AsList<Emplacement>();

        //Add data types to the data lists
        containerTypes.AddRange(_dataTypeService.GetAllContainerTypes());
        materialTypes.AddRange(_dataTypeService.GetAllMaterialTypes());
        emplacementTypes.AddRange(_emplacementRepository.GetByProperty("Owner.Id", ownerId.ToString(), "Id ASC"));

        //Create a view model from the data lists
        ContainerCreateViewModel containerCreateViewModel = new ContainerCreateViewModel
        {
            SerialNumber = id,
            ContainerTypes = new SelectList(containerTypes, "Id", "Display"),
            MaterialTypes = new SelectList(materialTypes, "Id", "Display"),
            ContainerEmplacements = new SelectList(emplacementTypes, "Id", "Name")
        };

        return PartialView("ReceptedContainer", containerCreateViewModel);
    }
}

ViewModel:

public class ContainerReceptionViewModel : ViewModel
{
    [HiddenInput]
    public int PickingId { get; set; }

    public int OwnerId { get; set; }

    [DisplayName(UiText.Client.CLIENT_NAME)]
    public int ClientId { get; set; }

    [DisplayName(UiText.ContainerReception.RECEPTION_DATE)]
    public DateTime ReceptionDate { get; set; }

    public SelectList Clients { get; set; }

    public SelectList Emplacements { get; set; }

    public bool NeedConfirmation { get; set; }

    public List<ContainerCreateViewModel> ReceivedContainers { get; set; }
}

查看:

@using Externalization
@using Prosyn.Domain
@using Prosyn.Domain.Application
@using Prosyn.Web.ViewModels.TubPickings
@using Prosyn.Web.ViewModels.Containers
@model Prosyn.Web.ViewModels.ContainerReception.ContainerReceptionViewModel

<h2>@UiText.PageTitles.CREATE_CONTAINER_RECEPTION</h2>

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

    <div class="form-horizontal">
        <div class="col-md-12">
            <div class="col-md-12">
                @Html.ValidationMessageFor(model => Model.ReceivedContainers, "", new { @class = "text-danger" })
                <hr />

                <div class="col-md-3 form-group">
                    <div>
                        @Html.LabelFor(model => model.ClientId, htmlAttributes: new { @class = "control-label" })
                        <div class="input-group">
                            @Html.DropDownListFor(model => model.ClientId, Model.Clients, UiText.Shipping.SELECT_CLIENT, htmlAttributes: new { @class = "form-control dropdown_search" })
                            @Html.ValidationMessageFor(model => model.ClientId, "", new { @class = "text-danger" })
                        </div>
                    </div>
                    <div>
                        @Html.LabelFor(model => model.ReceptionDate, htmlAttributes: new { @class = "control-label" })
                        <div class='input-group'>
                            <span class="input-group-addon">
                                <span class="fa fa-calendar"></span>
                            </span>
                            @Html.EditorFor(model => model.ReceptionDate, new { htmlAttributes = new { @class = "form-control datetime", @id = "arrivalTime" } })
                            <a href="#" class="btn btn-primary input-group-addon" onclick="timeNow('arrivalTime')"><i class="glyphicon glyphicon-time"></i></a>
                        </div>
                        @Html.ValidationMessageFor(model => model.ReceptionDate, "", new { @class = "text-danger" })
                    </div>
                </div>
            </div>
            <div class="col-md-12">
                <div id="TubPickingRows">
                    @foreach (ContainerCreateViewModel container in Model.ReceivedContainers)
                    {
                        Html.RenderPartial("ReceptedContainer", container);
                    }
                </div>
            </div>
            <div class="btn-group">
                <a href="@Url.Action(MVC.ContainerReception.AddOperation(""))" class="btn btn-info btn-outline" id="addTubPicking"><i class="fa fa-plus"></i> @UiText.TubPicking.ADD_OPERATION</a>
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-10" style="padding-top: 30px">
                <input id="btn-submit" type="submit" value="@UiText.Actions.SAVE" class="btn btn-success" />
                @Html.ActionLink(UiText.Actions.RETURN_LIST, MVC.Container.Index(), htmlAttributes: new { @class = "btn btn-default" })
            </div>
        </div>
    </div>
}

<script>
    var clickCount = @Model.ReceivedContainers.Count;

    $(document).ready(function() {
        $(window).keydown(function(event) {
            if(event.keyCode === 13) {
                event.preventDefault();
                return false;
            }
            return true;
        });
    });

    $("#addTubPicking").click(function () {
        clickCount++;
        $.ajax({
            url: this.href + '?id=@Model.PickingId-' + clickCount,
            cache: false,
            success: function (html) {
                $(html).hide().appendTo($("#TubPickingRows")).fadeIn();
                var elements = document.getElementsByClassName("select_all");

                for (var i = 0; i < elements.length; i++) {
                    elements[i].onclick = function() { this.select(); };
                }
            }
        });
        return false;
    });

    function deleteDriverBinPicking(sourceBtn) {
        $(sourceBtn).closest('.TubPickingRow').fadeOut('fast', function () { $(sourceBtn).closest('.TubPickingRow').remove(); });
    }

    function timeNow(id) {
        var now = new Date();
        var year = now.getFullYear();
        var month = now.getMonth() + 1;
        if (month < 10) month = "0" + month;
        var date = (now.getDate() < 10) ? "0" + now.getDate() : now.getDate();
        var hour = ((now.getHours() < 10) ? "0" + now.getHours() : now.getHours()) + ":" + ((now.getMinutes() < 10) ? "0" + now.getMinutes() : now.getMinutes());
        document.getElementById(id).value = year + "/" + month + "/" + date + " " + hour;
    }

    function updateForm(formId, color) {
        var form = document.getElementById("bin-pickup-" + formId);

        if (color === 0) {
            form.className = "panel-body panel-background-g";
        } else {
            form.className = "panel-body panel-background-b";
        }

        document.getElementById("transfert_form_" + formId).style.display = (color !== 1) ? "none" : "block";
        document.getElementById("pickup_form_" + formId).style.display = (color === 1) ? "none" : "block";;
    }
</script>

以及用于渲染容器的局部视图:

@using Externalization
@using Helpers.Html
@using Prosyn.Web.ViewModels
@model Prosyn.Web.ViewModels.Containers.ContainerCreateViewModel

@using (Html.BeginCollectionItem("ReceptedContainers"))
{
    <div class="TubPickingRow">
        <div class="col-md-4">
            <div class="panel panel-default">
                @Html.HiddenIndexerInputForModel()
                @Html.HiddenFor(model => model.Id)
                <div class="panel-heading">
                    <a class="btn btn-danger" href="javascript:void(0);" onclick="return deleteDriverBinPicking(this)">
                        <i class="fa fa-trash-o fa-lg"></i>
                    </a>
                    <b class="col-sm-offset-1">@UiText.TubPicking.PICKUP</b>
                </div>
                <div class="panel-body panel-background-b" id="bin-pickup-@Model.Id">
                    <div id="data_inputs_@Model.Id">
                        <div id="transfert_form_@Model.Id" style="display: block">
                            <div class="col-md-12">
                                @Html.LabelFor(model => model.SerialNumber, new { @class = "control-label" })
                                @Html.EditorFor(model => model.SerialNumber, new { @class = "form-control" })

                                @Html.ValidationMessageFor(model => model.SerialNumber, "", new { @class = "text-danger" })
                            </div>

                            <div class="col-md-12">
                                @Html.LabelFor(model => model.ContainerTypeId, new { @class = "control-label" })
                                @Html.DropDownListFor(model => model.ContainerTypeId, Model.ContainerTypes, htmlAttributes: new { @class = "form-control" })

                                @Html.ValidationMessageFor(model => model.ContainerTypeId, "", new { @class = "text-danger" })
                            </div>

                            <div class="col-md-12">
                                @Html.LabelFor(model => model.MaterialTypeId, new { @class = "control-label" })
                                @Html.DropDownListFor(model => model.MaterialTypeId, Model.MaterialTypes, htmlAttributes: new { @class = "form-control" })

                                @Html.ValidationMessageFor(model => model.MaterialTypeId, "", new { @class = "text-danger" })
                            </div>

                            <div class="col-md-12">
                                @Html.LabelFor(model => model.ContainerEmplacementId, new { @class = "control-label" })
                                @Html.DropDownListFor(model => model.ContainerEmplacementId, Model.ContainerEmplacements, htmlAttributes: new { @class = "form-control" })
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
}

1 个答案:

答案 0 :(得分:0)

我找到了答案,这很糟糕,仍然有一个名称错误。视图模型的名称为“ ReceivedContainers”,而其他所有模型都将其称为“ ReceptedContainers”。务必仔细检查每个拼写。