Member 14625950 Ответов: 1

Проблемы с список dropdownlist с вставленной в ASP.NET сердечник в MVC


Я м применении Кодекса первый подход в asp.net сердечник в MVC

Я создаю выпадающий список(страна,штат и город в таблице в mvc, но не вставленные countryname,statename,cityname) в базе данных см. изображение вставленных данных в базе данных.

Менеджер.в CS

public class Manager
{
    [Key]
    public int ManagerId { get; set; }
    public string ManagerName { get; set; }

    //Insertion in Manager table country state and city
    public int countryId { get; set; }
    public string countryname { get; set; }

    public int stateId { get; set; }
    public string statename { get; set; }

    public int cityId { get; set; }
    public string cityname { get; set; }

}

public class city
{
    public int cityId { get; set; }
    public string cityname { get; set; }

    [ForeignKey("state")]
    public int stateId { get; set; }
    public virtual state states { get; set; }
}

public class state
{
    public int stateId { get; set; }
    public string statename { get; set; }

    [ForeignKey("country")]
    public int countryId { get; set; }
    public virtual country countrys { get; set; }
}

public class country
{
    public int countryId { get; set; }
    public string countryname { get; set; }
}


DbContext можно.в CS
public class dbcontext : IdentityDbContext<Student>
   {
       public dbcontext(DbContextOptions<dbcontext> options) : base(options)
       {
           Database.EnsureCreated();
       }

       protected override void OnModelCreating(ModelBuilder builder)
       {
           base.OnModelCreating(builder);
       }

       public virtual DbSet<Manager> manages {get;set;}
       public virtual DbSet<country> countrys { get; set; }
       public virtual DbSet<state> states { get; set; }
       public virtual DbSet<city> citys { get; set; }

   }


HomeController:
public class HomeController : Controller
{
    private readonly dbcontext contxtclass;

    public HomeController(dbcontext contxtclass)
    {
        this.contxtclass = contxtclass;
    }

   [HttpGet]
    //not inserted countryname,stataname and cityname in database see the Referance image
    public IActionResult Create()
    {
        //bound the country table record
        List<country> countrylist = new List<country>();
        countrylist = (from countrys in contxtclass.countrys select countrys).ToList();
        countrylist.Insert(0,new country {  countryname = "Select" });
        ViewBag.listofcountry = countrylist;

        //bound the state table record
        List<state> statelist = new List<state>();
        statelist = (from states in contxtclass.states select states).ToList();
        statelist.Insert(0, new state { statename = "Select" });
        ViewBag.listofstate = statelist;

        //bound the city table record
        List<city> citylist = new List<city>();
        citylist = (from citys in contxtclass.citys select citys).ToList();
        citylist.Insert(0, new city { cityname = "Select" });
        ViewBag.listofcity = citylist;

        return View();
    }

    [HttpPost]
    public IActionResult Create(Manager manager)
    {
        contxtclass.Add(manager);
        contxtclass.SaveChanges();
        return View();
    }


создавать.cshtml по
@model WebApplication2.Models.Manager

@{
    Layout = null;
} 

<h2>Create</h2>
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly"></div>
            <div>
                <label asp-for="ManagerName"></label>
                <input asp-for="ManagerName"/>
                <span asp-validation-for="ManagerName"></span>
            </div>
            <div>
                <div asp-validation-summary="ModelOnly"></div>
                <div>
                    <label asp-for="countryname"></label>
                    <select asp-for="countryId"

                            asp-items="@(new SelectList(@ViewBag.listofcountry,"countryId","countryname"))"></select>
                </div>
            </div>
            <div>
                <div asp-validation-summary="ModelOnly"></div>
                <div>
                    <label asp-for="statename"></label>
                    <select asp-for="stateId"

                            asp-items="@(new SelectList(@ViewBag.listofstate,"stateId","statename"))"></select>
            </div>
            </div>
            <div>
                <div class="alert-danger" asp-validation-summary="ModelOnly"></div>
                <div>
                    <label asp-for="cityname"></label>
                    <select asp-for="cityId"

                            asp-items="@(new SelectList(@ViewBag.listofcity,"cityId","cityname"))"></select>
                </div>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
</form>

<div>
    <a asp-action="Index">Back to List</a>
</div>



дать значение ошибки не может быть нулевым???

При обработке запроса возникло необработанное исключение.
ArgumentNullException: значение не может быть null.
Имя параметра: items

Изображение Ошибки:

https://imgur.com/a/ENP8D2a

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

Я пытаюсь вставить имя страны,имя штата,имя города, не вставленное в таблицу(менеджер)??

1 Ответов

Рейтинг:
2

Richard Deeming

Это не совсем ясно из вашего вопроса, но, по-видимому, вы получаете ArgumentNullException когда вы отправляете форму, после того, как запись была вставлена.

Это потому, что вы только заселяете ViewBag списки по первоначальному запросу (the [HttpGet] действие). Когда вы выполняете [HttpPost] действие, а затем попробуйте отобразить вид, ни один из ViewBag списки присутствуют, так что вы в конечном итоге звоните new SelectList(null), что вызывает исключение.

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

Я бы также рекомендовал перенаправить пользователя на [HttpGet] метод после того, как вы добавили запись, а не просто снова отображаете представление.

private void PopulateCreateLookups()
{
    var countryList = contxtclass.countrys.ToList();
    countryList.Insert(0, new country { countryname = "Select" });
    ViewBag.listofcountry = countryList;
    
    var stateList = contxtclass.states.ToList();
    stateList.Insert(0, new state { statename = "Select" });
    ViewBag.listofstate = stateList;
    
    var cityList = contxtclass.citys.ToList();
    cityList.Insert(0, new city { cityname = "Select" });
    ViewBag.listofcity = citylist;
}

[HttpGet]
public IActionResult Create()
{
    PopulateCreateLookups();
    return View();
}

[HttpPost]
public IActionResult Create(Manager manager)
{
    if (!ModelState.IsValid)
    {
        PopulateCreateLookups();
        return View(manager);
    }
    
    contxtclass.manages.Add(manager);
    contxtclass.SaveChanges();
    return RedirectToAction("Create");
}


NB: Ваш countryname, statename и cityname не вставляются в таблицу менеджера, потому что вы не предоставляете для них никаких значений. Нет никаких редакторов, связанных с этими свойствами.

Но эти свойства все равно не имеют смысла. Вы уже ссылаетесь на таблицы country, state и city, которые содержат это имя. Вам не нужно хранить копию этого имени в таблице менеджера.


Member 14625950

@Richard Derming мой отладчик не может проверить этот код, почему???
if (!ModelState.Функция IsValid)
{
PopulateCreateLookups(); //отладчик не может войти внутрь???
возвратный вид(менеджер);
} //все еще не вставлено в statename,countryname и city name??

Richard Deeming

Что это за сообщение об ошибке?

Richard Deeming

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

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

public class Manager
{
    [Key]
    public int ManagerId { get; set; }
    public string ManagerName { get; set; }
    
    [ForeignKey("city")]
    public int cityId { get; set; }
    public city city { get; set; }
}
Конечно, это будет означать, что вы не сможете использовать asp-for по спискам стран и Штатов:
<div>
    <label for="countryid">Country</label>
    <select id="countryid" asp-items="@(new SelectList(@ViewBag.listofcountry,"countryId","countryname"))"></select>
</div>
<div>
    <label for="stateid">State</label>
    <select id="stateid" asp-items="@(new SelectList(@ViewBag.listofstate,"stateId","statename"))"></select>
</div>
<div>
    <label asp-for="cityid">City</label>
    <select asp-for="cityId" asp-items="@(new SelectList(@ViewBag.listofcity,"cityId","cityname"))"></select>
</div>
Но вы, вероятно, должны сделать эти каскадные выпадающие списки в любом случае:
Создание простого каскадного выпадающего списка в ASP.NET Core MVC с новыми помощниками тегов[^]