RuntimeBinderException: Невозможно выполнить привязку во время выполнения для пустой ссылки - PullRequest
2 голосов
/ 16 октября 2019

Я создаю страницу создания элемента, и на этой странице создания элемента есть всплывающая модальная таблица, в которой мы можем выбрать желаемый тип UoM. И обычно, когда эта форма отправляется со всеми заполненными полями, она сохраняет значения в базе данных. Но когда форма отправляется с одним или несколькими или со всеми не заполненными полями, она должна выдавать сообщение об ошибке, что поля обязательны для заполнения. Но это не так, и это показывает эту ошибку.

enter image description here

Это мой код

ItemController

using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Threading.Tasks;
using CRMandOMS.Models;
using CRMandOMS.ViewModels;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;

// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace CRMandOMS.Controllers
{
    public class ItemController : Controller
    {
        private readonly IItemRepository _itemRepository;

        private readonly IUoMRepository _uoMRepository;

        public ItemController(IItemRepository itemRepository, IUoMRepository uoMRepository)
        {
            _itemRepository = itemRepository;
            _uoMRepository = uoMRepository;
        }

        // GET: /<controller>/
        public ViewResult Index()
        {
            var model = _itemRepository.GetAll();

            return View(model);
        }

        public ViewResult Details(Guid? id)
        {
            Item item = _itemRepository.GetById(id.Value);

            return View(item);
        }

        [HttpGet]
        public ViewResult Create()
        {
            ItemCreateViewModel itemCreateViewModel = new ItemCreateViewModel()
            {
                UoMs = _uoMRepository.GetAll()
            };

            return View(itemCreateViewModel);
        }

        [HttpPost]
        public IActionResult Create(ItemCreateViewModel model)
        {
            if (ModelState.IsValid)
            {
                Item newItem = new Item
                {
                    Name = model.Name,
                    Price = model.Price,
                    UoMId = model.UoMId
                };

                _itemRepository.Insert(newItem);

                return RedirectToAction("Details", new { id = newItem.Id });
            }

            return View();
        }
    }
}

Создать

@model CRMandOMS.ViewModels.ItemCreateViewModel

@{
    ViewData["Title"] = "Item Create";
}

<h2>Item Create</h2>

<nav aria-label="breadcrumb">
    <ol class="breadcrumb">
        <li class="breadcrumb-item"><a asp-controller="Item" asp-action="Index">Item</a></li>
        <li class="breadcrumb-item active" aria-current="page">Create</li>
    </ol>
</nav>

<form enctype="multipart/form-data" asp-controller="Item" asp-action="Create" method="post" class="mt-3">

    <div class="form-group row">
        <label asp-for="Name" class="col-sm-2 col-form-label"></label>
        <div class="col-sm-10">
            <input asp-for="Name" class="form-control" placeholder="Name" />
            <span asp-validation-for="Name" class="text-danger"></span>
        </div>
    </div>

    <div class="form-group row">
        <label asp-for="Price" class="col-sm-2 col-form-label"></label>
        <div class="col-sm-10">
            <input asp-for="Price" class="form-control" placeholder="Price" />
            <span asp-validation-for="Price" class="text-danger"></span>
        </div>
    </div>

    <div class="form-group row">
        <label asp-for="UoMId" class="col-sm-2 col-form-label"></label>
        <div class="col-sm-10">
            <input asp-for="UoMId" id="uomid" class="form-control" hidden />
            <div class="input-group mb-3">
                <input id="uomname" type="text" class="form-control" placeholder="UoM" aria-label="UoM" aria-describedby="button-uom" disabled>
                <div class="input-group-append">
                    <button class="btn btn-outline-success" type="button" id="button-uom" data-toggle="modal" data-target="#uoMLookupTableModal">Select UoM</button>
                </div>
            </div>
            <span asp-validation-for="UoMId" class="text-danger"></span>
        </div>
    </div>

    <div asp-validation-summary="All" class="text-danger"></div>

    <div class="form-group row">
        <div class="col-sm-2"></div>
        <div class="col-sm-10">
            <a asp-controller="Item" asp-action="Index" class="btn btn-light">Back</a>
            <button type="submit" class="btn btn-success">Create</button>
        </div>
    </div>
</form>

@{
    await Html.RenderPartialAsync("_UoMLookup");
}

@section scripts {
    <script>
        $(document).ready(function () {
            var uoMTable = $("#uoMTable").DataTable({
                "columnDefs": [
                    {
                        "targets": [0],
                        "visible": false
                    }
                ],
                "order": [[1, "asc"]]
            });

            $('#uoMTable tbody').on('click', 'tr', function () {
                if ($(this).hasClass('table-success')) {
                    $(this).removeClass('table-success');
                }
                else {
                    uoMTable.$('tr.table-success').removeClass('table-success');
                    $(this).addClass('table-success');
                }
            });

            $("#getUoM").click(function () {
                var uomdata = uoMTable.row('.table-success').data();

                //alert(uomdata[0]);
                $('#uomid').val(uomdata[0]);

                //alert(uomdata[1]);
                $('#uomname').val(uomdata[1]);
            });
        });
    </script>
}

_UoMLookup

<div class="modal fade" id="uoMLookupTableModal" tabindex="-1" role="dialog" aria-labelledby="uoMLookupTableModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <table id="uoMTable" class="table table-striped table-bordered table-bordered nowrap" style="width:100%">
                    <thead>
                        <tr>
                            <td>Id</td>
                            <td>Name</td>
                            <td>Description</td>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach (UoM uom in Model.UoMs)
                        {
                            <tr>
                                <td class="uom-id">@uom.Id</td>
                                <td class="uom-name">@uom.Name</td>
                                <td>@uom.Description</td>
                            </tr>
                        }
                    </tbody>
                </table>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-light" data-dismiss="modal">Cancel</button>
                <button id="getUoM" type="button" class="btn btn-success" data-dismiss="modal">Select</button>
            </div>
        </div>
    </div>
</div>

ItemCreateViewModel

using CRMandOMS.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace CRMandOMS.ViewModels
{
    public class ItemCreateViewModel
    {
        [Required]
        [MaxLength(100, ErrorMessage = "Name cannot exceed 100 characters")]
        public string Name { get; set; }

        [Required(ErrorMessage = "{0} is required")]
        [Range(1000, 999999999)]
        public int Price { get; set; }

        [Required]
        public Guid UoMId { get; set; }
        public IEnumerable<UoM> UoMs { get; set; }

        public string PhotoPath { get; set; }
    }
}

Ответы [ 2 ]

0 голосов
/ 17 октября 2019

Но когда форма отправляется с одним или несколькими, либо со всеми не заполненными полями, она должна выдать сообщение об ошибке, что поля обязательны для заполнения. Но это не так, и он показывает эту ошибку.

У вас нет ссылки на сценарии проверки, убедитесь, что у вас есть _ValidationScriptsPartial.cshtml в папке Shared, затем измените код:

@section scripts {
  @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
  <script>
  //...
  </script>
}

Для ошибки на вашей странице, как и в других сообществах, вполне вероятно, что состояние модели недопустимо и выполняется return View() без возврата каких-либо данных для создания представления.

Однако ваше частичное представление не позволяет Model.UoMs быть нулевым.

В вашем действии Создать Post, если model содержит UoMs, вы можете просто использовать

return View(model)

в противном случае назначьте UoMs данные для модели так же, как вы сделали в действии Create Get, а затем верните их для просмотра.

Вы всегда можете использовать точку останова в действии Post для отладкирезультат.

0 голосов
/ 17 октября 2019

В методе HTTP POST Create (ItemController), если модель недопустима (поэтому ModelState.IsValid == false), вы не передаете модель в View. Убедитесь, что передали правильную модель, как показано в учебнике по методам управления .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...