C#ASP.NET MVC返回previous页 [英] C# ASP.NET MVC Return to Previous Page

查看:181
本文介绍了C#ASP.NET MVC返回previous页的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的控制器中的基本编辑方法重定向到一个顶级上市(「指数」)时,编辑成功。 MVC脚手架后,标准行为。

我试图改变这种编辑方法来重定向回previous页面(不索引)。由于我的编辑方法,不使用默认映射的输入参数ID,我第一次使用在previous URL传递尝试。

在我的编辑得的方法,我用这条线抢previous URL,它工作得很好:

  ViewBag.ReturnUrl = Request.UrlReferrer;

然后我用我的表单标签像这样发送这个返回URL来编辑后的方法:

  @using(Html.BeginForm(新{ID = ViewBag.ReturnUrl}))

现在,这是车轮掉了下来。我无法从id参数解析正确的URL。

的***的 更新:解决 的**的 *

使用加里的例子为指导,我是从ID到RETURNURL改变了我的参数,并使用一个隐藏字段来传递我的参数(而不是形式的标记)。教训:仅使用ID参数,它打算如何使用,并保持它的简单。它的工作原理吧。这是我更新code与笔记:

首先,我抢用Request.UrlReferrer因为我做了第一次的previous URL。

  //
    // GET:/问题/编辑/ 5    公众的ActionResult编辑(INT ID)
    {
        问题question = db.Questions.Find(ID);
        ViewBag.DomainId =新的SelectList(db.Domains,域ID,姓名,question.DomainId);
        ViewBag.Answers = db.Questions
                            .AsEnumerable()
                            。选择(D = gt;新建SelectListItem
                            {
                                文= d.Text,
                                值= d.QuestionId.ToString(),
                                选择= question.QuestionId == d.QuestionId
                            });
        //抓住previous网址,并将其添加到使用ViewData的或ViewBag模型
        ViewBag.returnUrl = Request.UrlReferrer;
        ViewBag.ExamId = db.Domains.Find(question.DomainId).ExamId;
        ViewBag.IndexByQuestion =的String.Format(IndexByQuestion / {0},question.QuestionId);
        返回查看(问题);
    }

和我现在从模型到[HttpPost]法的形式使用隐藏字段传递RETURNURL参数:

  @using(Html.BeginForm())
{
    <输入类型=隐藏的名字=RETURNURLVALUE =@ ViewBag.returnUrl/>
    ...

在[HttpPost]的方法,我们拉离隐藏字段参数并重定向到它....

  //
    // POST:/问题/编辑/ 5    [HttpPost]
    公众的ActionResult编辑(问题的问题,串RETURNURL)//添加参数
    {
        INT ExamId = db.Domains.Find(question.DomainId).ExamId;
        如果(ModelState.IsValid)
        {
            db.Entry(问题).STATE = EntityState.Modified;
            db.SaveChanges();
            //返回RedirectToAction(「指数」);
            返回重定向(RETURNURL);
        }
        ViewBag.DomainId =新的SelectList(db.Domains,域ID,姓名,question.DomainId);
        返回查看(问题);
    }


解决方案

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

您可以通过只返回视图中再次,而不是试图将用户重定向,这样你就可以使用的ModelState输出任何错误,也有更多的运气。

编辑:

根据反馈更新。您可以将previous URL中的视图模型,将其添加到一个隐藏字段然后在保存编辑的动作再次使用它。

例如:

 公众的ActionResult指数()
{
    返回查看();
}[HTTPGET] //这不是必须的
公众的ActionResult编辑(INT ID)
{
   //装入对象,并在视图退回
   视图模型视图模型=负载(ID);   //获取previous网址,并将其与视图模型存储
   视图模型$ P ​​$ pviousUrl = System.Web.HttpContext.Current.Request.UrlReferrer。   返回视图(视图模型);
}[HttpPost]
公众的ActionResult编辑(视图模型视图模型)
{
   //试图挽救发布对象,如果一切正常,返回索引,如果没有则再次返回编辑视图   BOOL成功=保存(视图模型);
   如果(成功)
   {
       返回RedirectToAction(视图模型$ P ​​$ pviousUrl);
   }
   其他
   {
      ModelState.AddModelError(有错误);
      返回视图(视图模型);
   }
}

您的视图BeginForm方法并不需要或者使用返回URL,你应该能够逃脱:

  @model视图模型@using(Html.BeginForm())
{
    ...
    <输入类型=隐藏的名字=previousUrlVALUE =@型号previousUrl/>
}

让我们回到你的表单操作张贴到不正确的URL,这是因为你传递一个URL作为ID参数,因此路由自动格式化的返回路径您的网址。

这是行不通的,因为你的表格将被张贴到一个控制器动作,将不知道如何保存编辑。您需要发布到您的攒动,然后再在它处理重定向。

I have a basic Edit method in my controller that redirects back to a top level listing ("Index") when the edit succeeds. Standard behavior after MVC scaffolding.

I am trying to change this Edit method to redirect back to the previous page (not Index). Since my Edit method wasn't using the default mapped input parameter "id", I first tried using that to pass in the previous URL.

In my Edit "get" method, I used this line to grab the previous URL and it worked fine:

ViewBag.ReturnUrl = Request.UrlReferrer;

I then sent this return URL to the Edit "post" method by using my form tag like this:

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

Now this is where the wheels fell off. I couldn't get the URL parsed from the id parameter properly.

*** UPDATE: SOLVED ***

Using Garry's example as a guide, I changed my parameter from "id" to "returnUrl" and used a hidden field to pass my parameter (instead of the form tag). Lesson learned: Only use the "id" parameter how it was intended to be used and keep it simple. It works now. Here is my updated code with notes:

First, I grab the previous URL using Request.UrlReferrer as I did the first time.

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

and I now pass the returnUrl parameter from the Model to the [HttpPost] method using a hidden field in the form:

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

In the [HttpPost] method we pull the parameter from the hidden field and Redirect to it....

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

解决方案

I am assuming (please correct me if I am wrong) that you want to re-display the edit page if the edit fails and to do this you are using a redirect.

You may have more luck by just returning the view again rather than trying to redirect the user, this way you will be able to use the ModelState to output any errors too.

Edit:

Updated based on feedback. You can place the previous URL in the viewModel, add it to a hidden field then use it again in the action that saves the edits.

For instance:

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 RedirectToAction(viewModel.PreviousUrl);
   }
   else
   {
      ModelState.AddModelError("There was an error");
      return View(viewModel);
   }
}

The BeginForm method for your view doesn't need to use this return URL either, you should be able to get away with:

@model ViewModel

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

Going back to your form action posting to an incorrect URL, this is because you are passing a URL as the 'id' parameter, so the routing automatically formats your URL with the return path.

This won't work because your form will be posting to an controller action that won't know how to save the edits. You need to post to your save action first, then handle the redirect within it.

这篇关于C#ASP.NET MVC返回previous页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆