xXxRevolutionxXx Ответов: 2

Выделите список и выберите список | ссылка на объект не указывает на экземпляр объекта.


- Привет ! Я пытаюсь реализовать список выбора (DropDownListFor) и список множественного выбора (ListBoxFor) в ASP.NET(MVC5), и при отправке формы я получаю исключение "ссылка на объект не установлена на экземпляр объекта". Я нашел кучу статей о переполнении стека, которые на самом деле не очень мне помогли. Я много чего перепробовал, но не слишком удачно.

Вот фотография исключения: [Исключением Цены,
кликни меня!
]

Что я уже пробовал:

Контроллер:

public ActionResult New()
        {
            List<string> availableImages = new List<string>();
            //here i an getting the path for all the available images from 
            // the database
            foreach (Image contextImage in _context.Images)
            {
                availableImages.Add(contextImage.FullName);
            }
            
            return View("New", new NewProductViewModel(availableImages));
        }


модель представления:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Mom_Website.Models;

namespace Mom_Website.ViewModels
{
    public class NewProductViewModel
    {
        public int Id { get; set; }

        [Required]
        [StringLength(40)]
        public string Name { get; set; }

        [Required]
        public string Description { get; set; }

        //This is the 'default photo' that will be displayed at the product
        //thumbnail(at the product's index)
        [Required]
        public string ThumbnailImage { get; set; }

        //This property contains the selected photos to be displayed on the
        //Details page of the product
        [Required]
        public IEnumerable<string> SelectedImages { get; set; }

        [Required]
        public int Price { get; set; }

        [Required]
        public int ShippingCost { get; set; }

        [Required]
        public int NumberAvailable { get; set; }

        //this field contains all the available photos on the database
        public IEnumerable<SelectListItem> MultiSelectAvailableImages { get; set; }

        public IEnumerable<SelectListItem> SelectListAvailableImages { get; set; }

        public NewProductViewModel(IEnumerable<string> availableImages)
        {
            this.MultiSelectAvailableImages = new MultiSelectList(availableImages);
            this.SelectListAvailableImages = new SelectList(availableImages);
        }

        public NewProductViewModel()
        {
        }
    }
}


Смотреть:

@model Mom_Website.ViewModels.NewProductViewModel

@{
    ViewBag.Title = "New";
}

<h2>New Product</h2>

@using (Html.BeginForm("Save", "Products"))
{
    <div class="form-group">
        @Html.LabelFor(m => m.Name)
        @Html.TextBoxFor(m => m.Name, new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.Name)
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Description)
        @Html.TextBoxFor(m => m.Description, new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.Description)
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.NumberAvailable)
        @Html.TextBoxFor(m => m.NumberAvailable, new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.NumberAvailable)
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Price)
        @Html.TextBoxFor(m => m.Price, new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.Price)
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.ShippingCost)
        @Html.TextBoxFor(m => m.ShippingCost, new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.ShippingCost)
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.ThumbnailImage)
        @Html.DropDownListFor(m => m.ThumbnailImage, Model.SelectListAvailableImages, "Select Default Image", new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.ThumbnailImage)
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.SelectedImages)
        @Html.ListBoxFor(m => m.SelectedImages, Model.MultiSelectAvailableImages, new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.SelectedImages)
    </div>
    @Html.HiddenFor(m => m.Id)
    @Html.AntiForgeryToken()
    <button type="submit" class="btn btn-primary">Save</button>
}

@section scripts
{
    @Scripts.Render("~/Bundles/jqueryval")
}

2 Ответов

Рейтинг:
20

OriginalGriff

Это одна из самых распространенных проблем, которые нам задают, и это также та, на которую мы меньше всего готовы ответить, но вы больше всего готовы ответить сами.

Позвольте мне просто объяснить, что означает ошибка: вы пытались использовать переменную, свойство или возвращаемое значение метода, но оно содержит null - что означает, что в переменной нет экземпляра класса.
Это немного похоже на карман: у вас есть карман в рубашке, в котором вы держите ручку. Если вы сунете руку в карман и обнаружите, что там нет ручки, вы не сможете подписать свое имя на листе бумаги - и вы получите очень забавный вид, если попытаетесь! Пустой карман дает вам нулевое значение (здесь нет ручки!), поэтому вы не можете сделать ничего такого, что обычно делали бы, когда извлекли свою ручку. Почему он пуст? Вот в чем вопрос - может быть, вы забыли взять ручку, когда уходили из дома сегодня утром, или, возможно, вы оставили ручку в кармане вчерашней рубашки, когда снимали ее вчера вечером.

Мы не можем сказать, потому что нас там не было, и, что еще важнее, мы даже не можем видеть вашу рубашку, не говоря уже о том, что находится в кармане!

Вернемся к компьютерам, и вы каким - то образом сделали то же самое-и мы не можем увидеть ваш код, а тем более запустить его и узнать, что содержит null, когда это не должно быть.
Но вы можете - и Visual Studio поможет вам здесь. Запустите свою программу в отладчике, и когда она выйдет из строя, VS покажет вам строку, на которой она обнаружила проблему. Затем вы можете начать просматривать различные его части, чтобы увидеть, какое значение равно null, и начать просматривать свой код, чтобы выяснить, почему. Поэтому поставьте точку останова в начале метода, содержащего строку ошибки, и снова запустите программу с самого начала. На этот раз VS остановится перед ошибкой и позволит вам изучить, что происходит, пройдя через код, глядя на ваши значения.

Но мы не можем этого сделать - у нас нет вашего кода, мы не знаем, как его использовать, если бы он у нас был, у нас нет ваших данных. Так что попробуйте - и посмотрите, сколько информации вы сможете узнать!


xXxRevolutionxXx

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

Я программирую уже около 2 лет, так что у меня есть довольно хорошее представление о том, что такое отладка. Мысль заключается в том, что все здесь является инстанцированным. Он должен работать, но не работает(да, это еще одна распространенная фраза в мире программирования). Дело в том, что здесь точки останова и т. д. не могут мне помочь, так как проблема заключается в настройке списков. Я все делал по инструкции(по крайней мере, мне так кажется), но все равно получаю это исключение.

OriginalGriff

Ошибка конкретно означает, что что - то является нулевым, где это не ожидается - и есть хороший шанс, что это в ваших данных, а не в вашем коде, - но мы не можем сказать, потому что у нас нет доступа к обоим во время работы. Поэтому, когда вы настраиваете списки, посмотрите на данные, которые вы используете для их настройки - что-то равно нулю, и пока вы не выясните точно, что именно, никто не сможет это исправить! :смеяться:

xXxRevolutionxXx

Принял твой ответ.

Рейтинг:
1

xXxRevolutionxXx

Итак ... после долгой отладки здесь я должен сказать, что проблема была действительно простой.

Первый, НЕ ИСПОЛЬЗОВАТЬ конструктор в КАКОЙ-НИБУДЬ способ, когда вы используете привязку модели. Это разрушит ваш мозг в процессе. Вместо этого установите значения при создании экземпляра ViewModel на контроллере. Например:

ViewModelClass myViewModel = new ViewModelClass();
myViewModel.ThePropertyIWantToSet = SomeData;

В этом и был корень проблемы.

Во-вторых, я ошибся в действии сохранения на контроллере. Я вернул представление после отправки туда данных... не проходя мимо ViewModel(конечно). Я изменяю это:
return View("New"); 
к:

return RedirectToAction("New");


Я надеюсь, что этот комментарий поможет людям в будущем !!


Graeme_Grant

Пожалуйста, не публикуйте решения ваших собственных проблем, а затем отметьте их как ответные. Это считается репутационным фермерством и может привести к тому, что вас вышвырнут.

Вместо этого включите это обновление в вопрос, нажав на виджет" улучшенный вопрос " выше. После этого, пожалуйста, удалите это решение.