【问题标题】:How to make a details page for every db item with its ID?如何为每个带有 ID 的数据库项目创建一个详细信息页面?
【发布时间】:2019-04-03 17:26:16
【问题描述】:

我有一个包含项目列表的视图 每个项目都有一个重定向到项目页面的操作链接

观点:


<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 是 db item id

必须显示每个项目详细信息页面的另一个视图:

@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 的链接时 它不起作用,它向我显示此错误消息:

参数字典包含“ElMatrodySite.Controllers.ArticleController”中方法“System.Web.Mvc.ActionResult Article(Int32)”的不可为空类型“System.Int32”的参数“ArtID”的空条目。可选参数必须是引用类型、可空类型或声明为可选参数。 参数名称:参数

System.ArgumentException:参数字典包含“ElMatrodySite.Controllers”中方法“System.Web.Mvc.ActionResult Article(Int32)”的不可为空类型“System.Int32”的参数“ArtID”的空条目。文章控制器”。可选参数必须是引用类型、可空类型或声明为可选参数。 参数名称:参数

路由配置:

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 }
            );
        }
    }
}

【问题讨论】:

  • 它显示错误消息,因为ArtID 为空
  • 将 public ActionResult Article(int ArtID) 更改为 public ActionResult Article(int id) 并更正 إقرأ المزيد »» to إقرأ المزيد »»
  • 这行代码有什么用articles = db.NewsData.Where(xn =&gt; xn.ArticleID == type.ArticleID).ToList();因为你没有在任何地方使用文章
  • @Rashedul.Rubel 我按照你说的做了,它给了我错误消息`传递到字典中的模型项是'System.Int32'类型,但是这个字典需要一个类型的模型项'System.Collections.Generic.IEnumerable1[ElMatrodySite.Models.NewsData]'.
  • @GabrielCostin 它在我上面提到的第一个视图中显示了一个包含数据库项目的列表

标签: c# sql-server asp.net-mvc


【解决方案1】:

好的,具体到您的情况,第一个问题在于您如何定义路由配置:

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] 错误。

此错误基本上意味着您向视图返回了不正确的模型。在您的情况下,您的视图需要一个类型的模型:IEnumerable&lt;ElMatrodySite.Models.NewsData&gt;,但您返回的是return View("Article", ArtID);,这是不正确的,因此您会看到此错误。

要解决此问题,您必须发送您的 View 期望的类型的模型。在您的情况下,它是 List&lt;NewsData&gt;

最后,您询问了如何在您的情况下使用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
}

【讨论】:

  • 还有一个问题,在详细信息视图页面中,我必须在@model 中使用IEnumerable 还是直接输入:@model ElMatrodySite.Models.NewsData
  • @kingkomand2o 您应该将其定义为IEnumerable&lt;ElMatrodySite.Models.NewsData&gt;,因为您将List&lt;NewsData&gt; 返回给视图。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-24
  • 1970-01-01
  • 1970-01-01
  • 2014-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多