首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >C# ASP.NET MVC返回上一页

C# ASP.NET MVC返回上一页
EN

Stack Overflow用户
提问于 2012-03-19 23:26:36
回答 4查看 117.8K关注 0票数 77

我的控制器中有一个基本的Edit方法,当编辑成功时,它会重定向回顶级列表(“Index”)。MVC搭建后的标准行为。

我正在尝试更改此Edit方法以重定向回上一页(而不是索引)。因为我的Edit方法没有使用默认的映射输入参数“id”,所以我首先尝试使用它来传入前面的URL。

在我的Edit“get”方法中,我使用下面这一行来抓取前面的URL,它工作得很好:

ViewBag.ReturnUrl = Request.UrlReferrer;

然后,我使用表单标记将此返回URL发送给Edit“post”方法,如下所示:

@using (Html.BeginForm(new { id = ViewBag.ReturnUrl }))

这就是轮子掉下来的地方。我无法从id参数中正确解析URL。

*更新:已解决的***

以Garry的例子为指导,我将参数从"id“更改为"returnUrl”,并使用隐藏字段传递参数(而不是表单标记)。学到的教训:只使用"id“参数,并保持其简单性。它现在起作用了。下面是我更新的代码和注释:

首先,我像第一次一样使用Request.UrlReferrer抓取前面的URL。

    //
    // GET: /Question/Edit/5

    public ActionResult Edit(int id)
    {
        Question question = db.Questions.Find(id);
        ViewBag.DomainId = new SelectList(db.Domains, "DomainId", "Name", question.DomainId);
        ViewBag.Answers = db.Questions
                            .AsEnumerable()
                            .Select(d => new SelectListItem
                            {
                                Text = d.Text,
                                Value = d.QuestionId.ToString(),
                                Selected = question.QuestionId == d.QuestionId
                            });
        // Grab the previous URL and add it to the Model using ViewData or ViewBag
        ViewBag.returnUrl = Request.UrlReferrer;
        ViewBag.ExamId = db.Domains.Find(question.DomainId).ExamId;
        ViewBag.IndexByQuestion = string.Format("IndexByQuestion/{0}", question.QuestionId);
        return View(question);
    }

现在,我使用表单中的隐藏字段将returnUrl参数从模型传递给HttpPost方法:

@using (Html.BeginForm())
{
    <input type="hidden" name="returnUrl" value="@ViewBag.returnUrl" />
    ...

在HttpPost方法中,我们从隐藏字段中提取参数并重定向到它...

    //
    // POST: /Question/Edit/5

    [HttpPost]
    public ActionResult Edit(Question question, string returnUrl) // Add parameter
    {
        int ExamId = db.Domains.Find(question.DomainId).ExamId;
        if (ModelState.IsValid)
        {
            db.Entry(question).State = EntityState.Modified;
            db.SaveChanges();
            //return RedirectToAction("Index");
            return Redirect(returnUrl);
        }
        ViewBag.DomainId = new SelectList(db.Domains, "DomainId", "Name", question.DomainId);
        return View(question);
    }
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-03-20 00:23:28

我假设(如果我错了,请纠正我),如果编辑失败,你想重新显示编辑页面,为了做到这一点,你正在使用重定向。

通过再次返回视图而不是尝试重定向用户,您可能会更幸运,这样您也可以使用ModelState输出任何错误。

编辑:

根据反馈进行了更新。您可以将以前的网址放在viewModel中,将其添加到隐藏字段,然后在保存编辑的操作中再次使用它。

例如:

public ActionResult Index()
{
    return View();
}

[HttpGet] // This isn't required
public ActionResult Edit(int id)
{
   // load object and return in view
   ViewModel viewModel = Load(id);

   // get the previous url and store it with view model
   viewModel.PreviousUrl = System.Web.HttpContext.Current.Request.UrlReferrer;

   return View(viewModel);
}

[HttpPost]
public ActionResult Edit(ViewModel viewModel)
{
   // Attempt to save the posted object if it works, return index if not return the Edit view again

   bool success = Save(viewModel);
   if (success)
   {
       return Redirect(viewModel.PreviousUrl);
   }
   else
   {
      ModelState.AddModelError("There was an error");
      return View(viewModel);
   }
}

视图的BeginForm方法也不需要使用此返回URL,您应该能够使用:

@model ViewModel

@using (Html.BeginForm())
{
    ...
    <input type="hidden" name="PreviousUrl" value="@Model.PreviousUrl" />
}

返回到您的表单操作发布到错误的URL,这是因为您将URL作为'id‘参数传递,因此路由会自动使用返回路径格式化您的URL。

这将不起作用,因为您的表单将发送到一个不知道如何保存编辑的控制器操作。您需要先发送到保存操作,然后在其中处理重定向。

票数 65
EN

Stack Overflow用户

发布于 2019-12-24 15:41:34

对于ASP.NET核心路由,您可以使用asp--*属性:

<form asp-action="Login" asp-route-previous="@Model.ReturnUrl">

假设您有一个具有操作的车辆控制器:

索引

详细信息

编辑

您可以从Index或Details编辑任何车辆,因此如果单击了从索引编辑,则必须在编辑后返回索引,如果单击了从详细信息编辑,则必须在编辑后返回到详细信息。

//In your viewmodel add the ReturnUrl Property
public class VehicleViewModel
{
     ..............
     ..............
     public string ReturnUrl {get;set;}
}



Details.cshtml
<a asp-action="Edit" asp-route-previous="Details" asp-route-id="@Model.CarId">Edit</a>

Index.cshtml
<a asp-action="Edit" asp-route-previous="Index" asp-route-id="@item.CarId">Edit</a>

Edit.cshtml
<form asp-action="Edit" asp-route-previous="@Model.ReturnUrl" class="form-horizontal">
        <div class="box-footer">
            <a asp-action="@Model.ReturnUrl" class="btn btn-default">Back to List</a>
            <button type="submit" value="Save" class="btn btn-warning pull-right">Save</button>
        </div>
    </form>

在您的控制器中:

// GET: Vehicle/Edit/5
    public ActionResult Edit(int id,string previous)
    {
            var model = this.UnitOfWork.CarsRepository.GetAllByCarId(id).FirstOrDefault();
            var viewModel = this.Mapper.Map<VehicleViewModel>(model);//if you using automapper
    //or by this code if you are not use automapper
    var viewModel = new VehicleViewModel();

    if (!string.IsNullOrWhiteSpace(previous)
                viewModel.ReturnUrl = previous;
            else
                viewModel.ReturnUrl = "Index";
            return View(viewModel);
        }



[HttpPost]
    public IActionResult Edit(VehicleViewModel model, string previous)
    {
            if (!string.IsNullOrWhiteSpace(previous))
                model.ReturnUrl = previous;
            else
                model.ReturnUrl = "Index";
            ............. 
            .............
            return RedirectToAction(model.ReturnUrl);
    }
票数 4
EN

Stack Overflow用户

发布于 2020-08-28 08:09:42

我知道这很晚了,但也许这会对别人有帮助。

我使用Cancel按钮返回到引用的url。在视图中,尝试添加以下内容:

@{
  ViewBag.Title = "Page title";
  Layout = "~/Views/Shared/_Layout.cshtml";

  if (Request.UrlReferrer != null)
  {
    string returnURL = Request.UrlReferrer.ToString();
    ViewBag.ReturnURL = returnURL;
  }
}

然后你可以这样设置你的按钮href:

<a href="@ViewBag.ReturnURL" class="btn btn-danger">Cancel</a>

除此之外,Jason Enochs的更新效果很好!

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9772947

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档