RedirectToAction传Model时URL数据暴露的三类技术问题咨询
Hey there, let's walk through your three questions clearly—these are super common pain points when working with action redirections in ASP.NET MVC (I’m making that assumption based on your mention of TempData and action routing):
1. Alternatives to TempData for hiding data from query strings
Absolutely, there are several server-side and client-side approaches to keep your model data out of the URL:
- Session Storage: Store your model in the user's session, then retrieve it in the target action. Just remember to clean up the session entry afterward to avoid unnecessary memory usage:
// In your first action Session["UserModel"] = myModel; return RedirectToAction("SecondAction"); // In your second action var model = Session["UserModel"] as YourModelType; Session.Remove("UserModel"); // Clean up after use - Context.Items (Server.Transfer): Use
Server.TransferRequestto pass control directly to the target action on the server side, with data stored inContext.Items. This keeps the client completely unaware of the transfer, so the URL stays the same:// First action Context.Items["MyModel"] = myModel; Server.TransferRequest("~/YourController/SecondAction"); return new EmptyResult(); // Second action var model = Context.Items["MyModel"] as YourModelType; - In-Memory Cache with a Unique Token: Store the model in a server-side cache (like
IMemoryCache) with a random unique token, then pass only the token via the URL. The target action uses the token to fetch the model from the cache:// First action var token = Guid.NewGuid().ToString(); _cache.Set(token, myModel, TimeSpan.FromMinutes(5)); // Set expiration return RedirectToAction("SecondAction", new { token }); // Second action if (_cache.TryGetValue(token, out YourModelType model)) { _cache.Remove(token); // Clean up // Use the model } - Direct Action Invocation: If you don’t need to change the URL in the browser, skip the redirect entirely and call the target action method directly from the first one:
return SecondAction(myModel);
2. Why redirects are client-initiated
This boils down to how HTTP works by design. When you call RedirectToAction, your server returns an HTTP 302 (or 303/307) status code, along with a Location header that specifies the target URL.
The browser’s job when receiving this response is to automatically send a new request to the URL in the Location header. This is intentional: it prevents users from accidentally resubmitting form data if they refresh the page (a core part of the Post/Redirect/Get design pattern) and ensures the browser’s address bar updates to the correct target URL.
In short, redirects are a way for the server to tell the client "go here instead"—so the client has to initiate that new request.
3. Can redirects pass data via the request body (Post method)?
By default, no—standard HTTP redirects (302/303) will convert any original Post request to a Get request when the client follows the redirect. That means you can’t send a request body with a standard redirect.
But there are workarounds if you need to send data via Post:
- Auto-Submit Hidden Form: Return a view from your first action that contains a hidden HTML form populated with your model data, then use JavaScript to auto-submit the form to the target action. This triggers a Post request with data in the body, and the URL won’t expose the data:
<!-- View returned from first action --> <form id="redirectForm" action="/YourController/SecondAction" method="post"> @Html.HiddenFor(m => m.Property1) @Html.HiddenFor(m => m.Property2) <!-- Add all model properties as hidden fields --> </form> <script> window.onload = function() { document.getElementById('redirectForm').submit(); }; </script> - HTTP 307 Status Code: This status code tells the browser to retain the original request method (Post) and body when following the redirect. However, note that browsers will often show a warning to users asking if they want to resubmit the data, which can be a poor user experience. To use this in ASP.NET:
return new RedirectResult("~/YourController/SecondAction", permanent: false) { StatusCode = 307 };
内容的提问来源于stack exchange,提问作者Syed Yawar

