I have a FormController with Index action and SimpleController with CorticonIndex action.
I am redirecting to CorticonIndex from Index action. My problem is, I have put a breakpoint at return RedirectToAction() and CorticonIndex().
So,Only for the first time I can see the execution by F11 but for the second time controller is not going to CorticonIndex().
How the RedirectToAction() will work?
Is it only one time execution or can we execute multiple time??
FormController
[HttpPost]
public ActionResult Index(FormCollection formCollection)
{
return RedirectToAction("CorticonIndex", " SimpleController");
}
SimpleController
public ActionResult CorticonIndex()
{
var viewModel = this.Model.GetViewModel(payLoad);
return View(CorticonResponseModel.viewName, viewModel);
}
How the RedirectToAction() will work?
It sends an HTTP 302 response to the browser of the web site along with a Location header. What the browser does with that is up to the browser. Normally, it will use the Location header to submit another request to your server. But, as this is entirely out of the application's control, there are no guarantees.
But in this case you are initially calling the server using an HTTP POST. If your browser reloads the page using an HTTP GET, it will not hit this same action method. If you have an HTTP GET action method named Index, it will call that one instead.
NOTE: FYI - if you remove the HttpPost attribute, your action method will respond to both GET and POST. But that is probably not the solution to your issue, as it is normal to have a separate action method in each case.
Related
In my React Native app, I'm trying to hit an endpoint in an API written in .Net. I've got the API code on my local machine, so I'm trying to hit it with a call to fetch(127.0.0.1:5000/api/token). This returns a 404 error. If I instead hit fetch(127.0.0.1:5000/), it returns successfully. The API code hit in this case is HomeController.cs, which contains this:
namespace InTowAPI2.Controllers
{
[AllowAnonymous]
[Route("/a")]
public class HomeController : Controller
{
// GET api/values
[HttpGet]
public string Get()
{
return "Ok";
}
}
}
When I make the call to fetch(127.0.0.1:5000/), it returns "Ok" and hits the breakpoint I set in HomeController.cs. The other file ValuesController.cs that should be hit when I call fetch(127.0.0.1:5000/api/token) contains this code (plus more after it):
namespace InTowAPI2.Controllers
{
[AllowAnonymous]
[Route("/api/[controller]")]
...
...
When I call fetch(127.0.0.1:5000/api/token), the breakpoint in ValuesController.cs is not hit, and it returns a 404 error.
What I tried to do to troubleshoot this was, since HomeController.cs was working, I replaced [Route("/")] with [Route("/api")], and made a call to fetch(127.0.0.1:5000/api). This also returned a 404 error.
What I Want To Know:
Why is it that hitting the API code containing [Route("/")] with fetch(127.0.0.1:5000/) works, but modifying it to hit [Route("/api")] with fetch(127.0.0.1:5000/api) throws a 404 error?
The issue is the routing.
[Route("/api/[controller]")]
This RouteAttribute definition will route the endpoint to the name of the controller.
The other file ValuesController.cs that should be hit...
Seems like you controller name is ValuesController, which would create an endpoint on /api/values, not /api/token.
To fix this, do one of the following things:
Change the name of the controller from ValuesController to TokenController.
Change the RouteAttribute from [Route("/api/[controller]")] to [Route("/api/token")].
I Write a ServiceStack Razor Page named 'default.cshtml'. I want to add a global response filter on it running, but it not work right. how to fixed it?
private static void AddFilters(IAppHost appHost)
{
appHost.GlobalResponseFilters.Add((req, res, dto) =>
{
res.AddHeader("X-Powered-By", "mylvgth");
});
}
GlobalResponseFilters are for requests that populate Request DTOs and are executed by Services. For other requests you can use PreRequestFilters which is executed at the start of a Request.
There are no Response filters for Razor pages as you can’t add Headers to a Request after its already written to the Response, only for “View Pages” which call Services first where the Response filter is executed before the page is rendered.
I have a controller like bellow
public class MenuController : Controller
{
//
// GET: /Menu/
public ActionResult Index()
{
return View();
}
public RedirectResult logout()
{
return RedirectPermanent("http://www.google.com");
}
}
and I set a break-point on logout for first time if I hit URL in address-bar localhost:(port number)/menu/logout code stop at breakpoint as expected but after that each and time code not stop breakpoint.
I spend around 2-3 hours and found some stack overflow link where some body write clear browser cache I do that and its working but only once ,that means I have to clear cache each time before debug .I use fire-fox(50.1.0) .try above code to replicate .please help I am stuck badly .
That's what RedirectPermanent() does. It basically tells the browser, "This resource will never be working again, so always request this redirected URL instead." So the browser remembers that and doesn't bother requesting a resource that it's been told will never work again.
If you want the redirect to be temporary, don't make it permanent:
return Redirect("http://www.google.com");
Because you're calling RedirectPermanent
Your browser is (correctly) caching the fact that visiting /logout permanently redirects to (in this case) Google.
It's performing a 301 redirect.
Use Redirect instead
public RedirectResult logout()
{
return Redirect("http://www.google.com");
}
I feel like this should be easy. I have an app where all I am trying to do is have a form page (index.jsp) that calls a servlet (CheckInfo.java) which sets a new header (myHeader) and redirects the user to another page (redirect.jsp). All of these files are on the same server. The index.jsp is sending the request just fine and CheckInfo is processing and redirecting, but myHeader is not showing up on redirect.jsp. I've read several posts talking about response.sendRedirect sends a 302 which doesn't pass headers and that I should use RequestDispatcher, but nothing seems to work. Is there no way to send headers from a servlet to a jsp?
Here is the servlet code:
response.setHeader("myHeader", "hey there");
response.sendRedirect("redirect.jsp");
I have also tried this:
response.setHeader("myHeader", "hey there");
RequestDispatcher view = request.getRequestDispatcher("redirect.jsp");
view.forward(request, response);
And I have this in redirect.jsp:
System.out.println(request.getHeader("myHeader"));
This does not print anything.
If the answer to my question is no... then I would settle for a way to set the header once I got back to the jsp. My reverse proxy is looking for a specific header to determine whether or not to perform an action. Obviously I tried response.addHeader() on redirect.jsp, but the page has already loaded at that point so that just made me feel dumb.
response.setHeader("myHeader", "hey there");
response.sendRedirect("redirect.jsp");
You are adding it as response header and it is 302 response. Browser on seeing a 302 response will just look for Location header and fire a new request to this location. Custom headers in the response are untouched whereas you are expecting these custom response headers to be included in the request (to new redirect location) which is not being sent.
Solution:-
1. you can use request dispatcher and forward the request instead of external redirect. And you need to use request attributes here.
2. you can call submit form using an ajax request may be jquery like and handle the response manually(for 302 response) but would not suggest you to use this approach as it is not a cleaner and intuitive approach. Just mentioning so that you know there are other ways to achieve this.
The problem is that the redirect() method of the response initiates a new request altogether, thereby loosing the attributes that were set before redirecting. Luckily there is a fluent way of solving the problem still. See below
response.setHeader("myHeader", "hey there");
request.getRequestDispatcher("redirect.jsp").forward(request, response);
Then in your destination you can do response.getHeaders("myHeader")
I have tested the code.
I hope it's clear that in case of asking the client to redirect to another URL - the browser shall not honor the cookies.
However, the 2nd method - where server forwards the request is feasible. The main mistake appears to be in mutating the response while we are supposed to change the request.
Then again, one cannot directly mutate a HttpServletRequest object. Here is one way to do so:
HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(request){
public String getHeader(String name) {
String value = super.getHeader(name);
if(Strings.isNullOrEmpty(value)) {
...
value = myNewHeader;
}
return value;
}
public Enumeration<String> getHeaders(String name) {
List<String> values = Collections.list(super.getHeaders(name));
if(values.size()==0) {
...
values.add(myNewHeader);
}
return Collections.enumeration(values);
}
public Enumeration<String> getHeaderNames() {
List<String> names = Collections.list(super.getHeaderNames());
names.add(myNewHeaderName);
...
return Collections.enumeration(names);
}
}
Followed by:
RequestDispatcher view = request.getRequestDispatcher("redirect.jsp");
// OR (If you can get servletContext)
RequestDispatcher view = servletContext.getRequestDispatcher("redirect.jsp");
view.forward(requestWrapper, response);
Reference:
https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequestWrapper.html
For the headers case - getHeader(), getHeaders() and getHeaderNames() fn in the reqWrapper obj need Overriding.
Similarly you can override cookies and params.
See also: Modify request parameter with servlet filter
NOTE: It might not be possible to forward a req to an endpoint which expects a different MIME type.
A client side redirect creates a new HTTP request/response pair.
This link may help you more on debugging perspective -
Sending Custom headers
I wrote a spring-mvc controller method to get an array of values in the request parameter.The method looks like below
/**
Trying to get the value for request param foo which passes multiple values
**/
#RequestMapping(method=RequestMethod.GET)
public void performActionXX(HttpServletRequest request,
HttpServletResponse response,
#RequestParam("foo") String[] foo) {
......
......
}
The above method works fine when the request url is in below format
...?foo=1234&foo=0987&foo=5674.
However when the request url is in below format the server returns 400 error
...?foo[0]=1234&foo[1]=0987&foo[2]=5674
Any idea how to fix the method to cater to the second format request url?
This is not possible with #RequestParam. What you can do is implement and register your own HandlerMethodArgumentResolver to perform to resolve request parameters like
...?foo[0]=1234&foo[1]=0987&foo[2]=5674
into an array. You can always checkout the code of RequestParamMethodArgumentResolver to see how Spring does it.
Note that I recommend you change how the client creates the URL.
The server is supposed to define an API and the client is meant to follow it, that's why we have the 400 Bad Request status code.
I resolved this issue using the request.getParameterMap().Below is code.
Map<String,String> parameterMap= request.getParameterMap();
for(String key :parameterMap.keySet()){
if(key.startsWith("nameEntry")){
nameEntryLst.add(request.getParameter(key));
}
}