在ASP.NET MVC中使用RedirectToAction的方法

33

我想发布一些有关 ASP.Net MVC 的问题。我对网络开发不熟悉,但是我被分配到了一个项目的网络部分。我们正在执行以下操作:首先,我们为个人数据创建getset属性:

public class Person
{
    public int personID {get;set;}
    public string personName {get;set;}
    public string nric {get;set;}
}

登录后,我们将数据放入一个名为Person的类对象中,并使用以下方式RedirectToAction

return RedirectToAction("profile","person",new { personID = Person.personID});

它正常工作,但参数显示在URL中。 我如何隐藏它们,还能隐藏操作名称吗?请给我一些示例指导我正确的方法。


我认为如果你不希望参数在URL中可见,你应该使用POST方法将其发送到表单中。这样,你仍然可以在FormCollection中访问它,但其他人在URL中看不到它。但是我对这一切也很陌生。 - Bohn
4个回答

47

参数显示在URL中是因为这是传递给RedirectToAction的第三个参数——路由值。

默认路由是{controller}/{action}/{id}

因此,这段代码:

return RedirectToAction("profile","person",new { personID = Person.personID});

将会产生以下URL/路由:

/Person/Profile/123

如果你想要一个更简洁的路由,像这样(例如):

/people/123

创建一个新的路由:

routes.MapRoute("PersonCleanRoute",
                "people/{id}",
                new {controller = "Person", action = "Profile"});

你的 URL 应该是干净的,就像上面的那样。

或者,你可能不想使用 ID,可以使用其他唯一标识符 - 如昵称。

因此,URL 可以像这样:

people/rpm1984

要实现这个,只需更改你的路由:

routes.MapRoute("PersonCleanRoute",
                    "people/{nickname}",
                    new {controller = "Person", action = "Profile"});

而你的操作方法:

public ActionResult Profile(string nickname)
{

}

而你的RedirectToAction代码:

return RedirectToAction("profile","person",new { nickname = Person.nickname});

那是你想要的吗?


如果您不想传递任何参数,只需执行 return RedirectToAction("profile","person"); 即可。但是这将生成 /person/profile,作为 URL 并不真正合理 - 这就是为令我要求您给出所需 URL 示例的原因。 - RPM1984
谢谢你的回复,朋友。我想要展示类似于“人物/个人资料”的内容,但是不需要参数显示在URL中。我的意思是我会传递参数,但是不希望在URL中显示。祝好,Chong。 - Chong
你如何在不显示在URL中的情况下传递参数?你将在哪里传递参数?我认为你有些困惑了。这不是代码中的方法 - 这是HTTP,有参数和表单提交值。 - RPM1984
好的朋友,那么我如何将参数传递给另一个控制器的操作呢? 例如,我有一个登录控制器,在登录后,我将传递登录信息,例如personid到Person Controller,并显示个人资料。我该怎么做?抱歉我的英语不好。现在我使用这种方式,在帐户控制器中“return RedirectToAction(“profile”,“person”,new { personID = Person.personID});”,它调用person控制器的profile操作。然后,我根据我传递的PersonID从数据库加载个人数据。但是,我不想在URL中显示参数。我在asp.net mvc中该怎么做?问候 Chong - Chong
@Chong - 我认为你对RedirectToAction的使用有些困惑。在Web-forms(常规ASP.NET)中,它基本上执行的是“Response.Redirect(“www.somewhere.com”)”。换句话说,这是一个HTTP重定向。这也是你应该做的。因此,你需要考虑你要重定向到哪里 - 你需要某种标识符来抓取用户 - 这是一个重定向 - 你需要通过URL传递信息。通过ID或其他标识符进行传递。另一种选择 - 如果你正在使用Forms身份验证 - 你可以从forms auth ticket获取用户信息。 - RPM1984
显示剩余2条评论

9

如果您不希望参数显示在地址栏中,您需要在重定向之间将其存储在服务器上的某个位置。一个很好的实现方式是使用TempData。以下是一个示例:

public ActionResult Index()
{
    TempData["nickname"] = Person.nickname;
    return RedirectToAction("profile", "person");
}

现在,在个人资料操作中,您正在重定向以从TempData中获取它:

public ActionResult Profile()
{
    var nickname = TempData["nickname"] as string;
    if (nickname == null)
    {
        // nickname was not found in TempData.
        // this usually means that the user directly
        // navigated to /person/profile without passing
        // through the other action which would store
        // the nickname in TempData
        throw new HttpException(404);
    }
    return View();
}

在底层,TempData使用Session进行存储,但在重定向后它将被自动清除,所以该值只能被使用一次,这也是你所需要的:存储、重定向、提取。

没错,可以用这个方法。但是你真的想在一个重定向上进行序列化/反序列化操作吗?如果他正在使用表单身份验证,他可以从票证中获取用户信息。 - RPM1984
感谢您所有的回复,我的问题是当我刷新页面时TempData消失了并且出现了错误。我该如何处理? - Chong
如果你使用“Peek”方法读取“TempData”,它将在下一个请求中保留。 stringstr = TempData.Peek("Td").ToString(); 有关更多TempData详细信息,请参考以下文章: http://www.codeproject.com/Articles/818493/MVC-Tempdata-Peek-and-Keep-confusion - Sugar Bowl

1

这可能是解决当页面刷新后TempData丢失的问题的方法:

在操作方法中第一次获取TempData时,将其设置为视图数据并编写以下检查:

public ActionResult Index()
{
    TempData["nickname"] = Person.nickname;
    return RedirectToAction("profile", "person");
}

现在在个人资料操作中:

public ActionResult Profile()
{
    var nickname = TempData["nickname"] as string;

    if(nickname !=null)
        ViewData["nickname"]=nickname;

    if (nickname == null && ViewData["nickname"]==null)
    {
        throw new HttpException(404);
    }
    else
    {
        if(nickname == null)
            nickname=ViewData["nickname"];
    }

    return View();
}

0

临时数据只能处理单个后续请求。因此,在刷新页面后,值就会消失。为了解决这个问题,我们在这种情况下可以使用 Session 变量。请尝试以下方法:

public ActionResult Index(Person _person)
{
    Session["personNickName"] = _person.nickName;
    return RedirectToAction("profile", "person");
}

在“profile”操作方法中:
public ActionResult profile()
{
    Person nickName=(Person)Session["personNickName"];
    if(nickName !=null)
    {
    //Do the logic with the nickName
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接