【问题标题】:ASP.NET MVC Redirect with model带有模型的 ASP.NET MVC 重定向
【发布时间】:2011-04-30 03:30:52
【问题描述】:

我的控制器中目前有一个方法,它接受表单集合、保存数据,然后在“详细信息”页面中显示数据。目前,代码目前看起来像:

[HttpPost]
public ActionResult Create(PersonModel person)
{
    if (person.IsValid())
    {
        person.additionalData = "Person created successfully";
        return View("Details", person);
    }
}

问题在于以这种方式返回详细信息视图会保留 URL mysite/Person/Create - 理想情况下,我希望 URL 是 mysite/Person/Details/{PersonId}。

我相信这一定是可能的。显然,我可以使用 Response.Redirect,但是这不允许我将模型传递给视图。据我所知,我无法使用 RedirectToAction 传递模型?

感谢您的帮助。

编辑:确认 - Create 操作生成的模型与 Details 操作创建的默认模型不同。因此,直接重定向到 Action 并传递 Id 不起作用,因为生成的模型不正确。为了提供更多上下文,来自 Create 操作的模型包含一个附加值,表示“成功创建人员”,如果我重定向到 Details 操作,则此消息不会出现在模型中。

【问题讨论】:

    标签: c# asp.net asp.net-mvc asp.net-mvc-2


    【解决方案1】:

    直接来自我自己的应用程序:

    public ActionResult Create(Booking item)
    {
        if (ModelState.IsValid)
        {
            int newID = _tasks.Create(item);
            // NEW section to emulate model being populated for use in Details view
            TempData["additionalData"] = "Person created successfully";
            return RedirectToAction("Details", new { id = newID });
        }
        else
        {
            return View();
        }
    }
    

    那么,您的“详细信息”操作不能是这样的吗:

    public ActionResult Details(int id)
    {
        var item = _tasks.GetByKey(id);
        var additionalData = TempData["additionalData"];
        if(item != null) {
            if(additonalMessage!=null)
            {
                item.additionalData = additionalData;
            }
            return View(item);
        }
        else
            return View("Notfound");
    }
    

    你不能采用类似的方法吗??

    您可以按照约定进行重定向并设置一个标志(在上面的临时数据上)给出此消息吗? tempadata 标志只能在 Create 操作中设置,因此只会在创建新的“人”对象时发生。因此,Details 操作只会将其显示为 Create 操作的结果

    【讨论】:

    • 这是要走的路。如果 tempdata 中的简单消息还不够,您可以将整个 PersonModel 对象放入 tempdata 并在您的 Details 操作方法中从 tempdata 中取回它。
    【解决方案2】:

    您可以使用TempData 来补充提供的内容(使用RedirectToAction 和路由)

    [HttpPost]
    public virtual ActionResult Create(IEnumerable<OrderItem> orderItems)
        {
            if (orderItems.Count() == 0)
            {
                return RedirectToAction("NoOrderItems");
            }
            else
            {
                TempData["orderItems"] = orderItems;
                return RedirectToAction("Confirm");
            }
        }
    
        [HttpGet]
        public virtual ActionResult Confirm()
        {
            var orderItems = TempData["orderItems"] as IEnumerable<OrderItem>;
            if (orderItems == null || orderItems.Count() == 0)
            {
                this.InvokeHttp404(ControllerContext.HttpContext);
            }
    
            return View(orderItems);
        }
    

    我将它用于我可能不想在后续请求中再次创建或尚未完全保留在数据库中的项目。有了这个,我不需要在我的视图中进行空检查,因为只有在有数据的情况下才能“获取”确认页面。

    【讨论】:

    • 很棒的代码我还没有测试过,但很快就必须在这样的组件上工作,我有一个问题,如果我刷新页面,它会工作还是临时数据会过期
    【解决方案3】:

    请注意,您也可以采用 MvcContrib 的类型安全方法并执行

    return this.RedirectToAction<MyController>(c => c.Details(person.PersonID));
    

    【讨论】:

    【解决方案4】:

    这将带您进入详细信息模型,并传递 ID。

    return RedirectToAction("Details", new { id = person.PersonID });
    

    【讨论】:

    • 您好,问题在于默认操作不会使用与通过“创建”操作相同的数据填充模型。查看其他答案,最好的解决方案似乎是 TempData。
    • 您可以创建一个 InitializeModel 方法,为您完成所有数据分配魔法..
    猜你喜欢
    • 2011-09-28
    • 2019-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多