You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET MVC:如何将URL中的ID从控制器传递到视图?求替代方案

嘿,我来给你几个更靠谱的实现思路,解决你现在获取URL中项目ID并配合ViewModel的问题:

方法1:把ID直接整合进ViewModel(最推荐,符合MVC设计)

与其在视图里硬去读取路由数据,不如直接把需要的ID放到ViewModel里,让控制器和视图的交互更清晰:

首先修改你的Multipledata模型,新增一个ProjectId属性:

public class Multipledata
{
    public int ProjectId { get; set; }
    public IEnumerable<Projects> projectss { get; set; }
    public IEnumerable<ProjectNotes> projectnotess { get; set; }
}

然后在控制器里,把URL传来的ID赋值给ViewModel的这个属性:

public ActionResult ViewProject(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    BextecODBEntities DB = new BextecODBEntities();
    var mymodel = new Multipledata();
    mymodel.ProjectId = id.Value; // 把URL中的ID存入ViewModel
    mymodel.projectss = DB.Projects.ToList();
    mymodel.projectnotess = DB.ProjectNotes.ToList();
    return View("ViewProject", mymodel);
}

最后在视图里,直接使用ViewModel里的ProjectId做判断,不用再依赖路由数据:

@foreach(var item in Model.projectss)
{
    if(item.ID == Model.ProjectId)
    {
        @Html.DisplayText($"You have clicked on Project ID: {item.ID}")
    }
}

这种方式的好处是,视图只需要依赖ViewModel的约定,不用关心ID是从哪里来的,代码更易维护,也符合MVC分离关注点的原则。

方法2:只加载当前ID对应的项目数据(性能更优)

如果你的视图只需要展示当前点击的项目信息,完全没必要把所有Projects数据都查出来,这样能减少数据库压力,视图代码也更简洁:

先给Multipledata新增一个CurrentProject属性:

public class Multipledata
{
    public Projects CurrentProject { get; set; }
    public IEnumerable<ProjectNotes> projectnotess { get; set; }
}

然后修改控制器,只查询目标项目和对应笔记:

public ActionResult ViewProject(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    BextecODBEntities DB = new BextecODBEntities();
    // 只查询当前ID的项目
    var targetProject = DB.Projects.FirstOrDefault(p => p.ID == id);
    if(targetProject == null)
    {
        return HttpNotFound(); // 项目不存在时返回404,更友好
    }
    var mymodel = new Multipledata();
    mymodel.CurrentProject = targetProject;
    // 还可以只查询该项目对应的笔记,减少数据量
    mymodel.projectnotess = DB.ProjectNotes.Where(pn => pn.ProjectID == id).ToList();
    return View("ViewProject", mymodel);
}

视图里就不用循环判断了,直接展示:

@Html.DisplayText($"You have clicked on Project ID: {Model.CurrentProject.ID}")
<!-- 还能直接展示项目的其他属性,比如名称、描述等 -->
<p>Project Name: @Model.CurrentProject.Name</p>

这个方法不仅代码更简洁,还能提升页面加载速度,推荐在实际项目中使用。

方法3:用ViewBag临时传递ID(应急备选,不推荐长期用)

如果不想修改ViewModel,也可以用ViewBag临时传递ID,但这种方式是动态类型,编译时没有类型检查,容易出错,只适合快速测试:

控制器里添加:

public ActionResult ViewProject(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    BextecODBEntities DB = new BextecODBEntities();
    var mymodel = new Multipledata();
    mymodel.projectss = DB.Projects.ToList();
    mymodel.projectnotess = DB.ProjectNotes.ToList();
    // 把ID存入ViewBag
    ViewBag.ProjectId = id.Value;
    return View("ViewProject", mymodel);
}

视图里使用:

@foreach(var item in Model.projectss)
{
    if(item.ID == (int)ViewBag.ProjectId)
    {
        @Html.DisplayText($"You have clicked on Project ID: {item.ID}")
    }
}

最后要确认的一点

记得检查你的路由配置,确保路由规则里包含id参数,比如默认路由:

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

如果路由没配置id,控制器就无法正确获取URL中的ID,这也是常见的坑点。

内容的提问来源于stack exchange,提问作者Zack Antony Bucci

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:52:28