Как сделать страницу деталей для каждого элемента БД с его идентификатором? - PullRequest
0 голосов
/ 02 апреля 2019

У меня есть представление, которое содержит список элементов каждый элемент имеет ссылку действия, которая перенаправляет на страницу элемента

вид:


<div class="row">
        @foreach (var item in Model)
        {
            <div class="card text-white bg-secondary mb-3" style="max-width: 400px;">
                <img class="card-img-top" src="@ViewBag.Path" alt="Card image" style="width:100%">
                <div class="card-body">
                    <h4 class="card-title">@item.ArticleTitle</h4>
                    <a onclick="location.href='@Url.Action("Article", "Article", new { Controller = "Account", Action = "SignIn", id = item.ArticleID })'" class="btn btn-primary stretched-link">إقرأ المزيد »»</a>
                </div>
            </div>
        }
    </div>

ссылка на это действие - / Article / Article / 4 Как 4 это идентификатор элемента БД

другой вид, который должен отображать каждую страницу детализации элемента:

@model IEnumerable<ElMatrodySite.Models.NewsData>

<h2>@Html.DisplayNameFor(mode => mode.ArticleTitle)</h2>
<img src=@ViewBag.Path style="max-width:40%;max-height:400px;" />
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.ArticleTitle)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.ArticleText)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.ArticlePostDate)
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.ArticleTitle)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ArticleText)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ArticlePostDate)
            </td>
            <td>
                @Html.ActionLink("EditArticle", "Article", new { id = item.ArticleID }) |
                @using (Html.BeginForm("Delete", "Article", FormMethod.Post))
                {
                    @Html.ActionLink("Delete", "Article", new { id = item.ArticleID })
                }
            </td>
        </tr>
    }

</table>

контроллер:

[HttpGet]
        [AllowAnonymous]
        public ActionResult Article(int ArtID)
        {
            using (MatrodyEntities db = new MatrodyEntities())
            {
                db.NewsData.Find(ArtID);
                return View("Article", ArtID);
            }

        }
        [AllowAnonymous]
        public ActionResult Articles()
        {
            List<NewsData> articles = new List<NewsData>();
            using (MatrodyEntities db = new MatrodyEntities())
            {
                var type = new NewsData();
                articles = db.NewsData.Where(xn => xn.ArticleID == type.ArticleID).ToList();
                ViewBag.Count = db.NewsData.SqlQuery("SELECT * FROM dbo.NewsData").Count();
                return View(from NewsData in db.NewsData.ToList() select NewsData);
            }
        }

после этого каждый раз, когда я иду по ссылке, как эта статья / статья / 4 это не работает, и это показывает мне это сообщение об ошибке:

Словарь параметров содержит пустую запись для параметра 'ArtID' ненулевого типа 'System.Int32' для метода 'System.Web.Mvc.ActionResult Article (Int32)' в ElMatrodySite.Controllers.ArticleController '. Необязательный параметр должен быть ссылочным типом, обнуляемым типом или быть объявлен как необязательный параметр. Имя параметра: параметры

System.ArgumentException: словарь параметров содержит пустую запись для параметра 'ArtID' ненулевого типа 'System.Int32' для метода 'System.Web.Mvc.ActionResult Article (Int32)' в 'ElMatrodySite.Controllers. ArticleController. Необязательный параметр должен быть ссылочным типом, обнуляемым типом или быть объявлен как необязательный параметр. Имя параметра: параметры

RouteConfig:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace ElMatrodySite
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}

1 Ответ

0 голосов
/ 03 апреля 2019

Хорошо, чтобы быть конкретным в вашем случае, первая проблема заключается в том, как вы определили конфигурацию вашего маршрута:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

Вы можете сделать любую из этих двух вещей:

1) Измените имя вашего параметра в ActionResult, если вы используете конфигурацию маршрута по умолчанию:

[HttpGet]
[AllowAnonymous]
public ActionResult Article(int id)
{
  using (MatrodyEntities db = new MatrodyEntities())
  {
    db.NewsData.Find(ArtID);
    return View("Article", id);
  } 
}

2) Добавить новый маршрут к статье:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    //Add your route here
    routes.MapRoute(
     "GetArticle", 
     "Article/{ArtID}", 
     new { controller = "Article", action = "Article" }
    );

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional}
    );
}

Как только вы выполните один из этих двух методов, вы получите ошибку System.InvalidOperationException: The model item passed into the dictionary is of type 'System.Int32', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[ElMatrodySite.Models.NewsData].

Эта ошибка в основном означает, что вы возвращаете неверную модель в свой View. В вашем случае ваш View ожидает модель типа: IEnumerable<ElMatrodySite.Models.NewsData>, но вы возвращаете обратно return View("Article", ArtID);, что неверно, и, следовательно, вы видите эту ошибку.

Чтобы решить эту проблему, вам необходимо отправить модель типа, ожидаемого вашим представлением. В вашем случае это List<NewsData>.

Наконец, вы спросили, как использовать FirstOrDefault() в вашем случае. Вы используете FirstOrDefault(), когда не уверены, будут ли указанные критерии возвращать запись или нет из вашей Коллекции. Теперь я не совсем уверен, что у меня есть полный код для вашего метода ActionResult, но вы можете добавить FirstOrDefault() следующим образом:

public ActionResult Article(int id)
{
    List<NewsData> oneList = new List<NewsData>();
    var data = new NewsData();

    //Return the first element that matches the specified criteria or null if nothing is found
    data=db.NewsData.Where(xx => xx.ArticleID == data.ArticleID).FirstOrDefault();

    data.ArticleID = id;
    return View(from NewsData in db.NewsData.ToList() select NewsData);
}

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

if(data== null)
{
do something
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...