I was trying to redirect from the Account controller (Account/Login) to User/Index by doing below syntax.
return RedirectToAction("Index", "User");
it shows up the correct view but the URL still persist as Account/Login. Can anyone suggest how can i achieve the same. I have tried some of the searches from google but none of them works for me.
It's an issue caused by jQuery-mobile. By default, jQM will make forms use ajax calls, as this is how page navigation is performed in the framework. AJAX navigation is explained in more detail here.
The solution is to add data-ajax="false" to the form tag used for the initial server call.
So your form would look like this:
#using (Html.BeginForm("Login", "Account", FormMethod.Post, new { data_ajax = "false" }))
Related
I am currently finding problem with my submit button.
I have a page (say Page A) and within this "Page A", I called a PartialView using the RenderAction("ActionName", "Controller", "Parameters").
The PartialView displays correctly. There is a BeginForm("Action", "Controller", null, FormMethod.Post, new { enctype = "multipart/form-data"}) and a Submit button in this "Page A" and when I click on the button, the formpost method called the RenderAction() instead of the FormPost method.
Please help me solve this challenge since my search for solution on this forum and elsewhere is not yielding any results.
You must use Ajax.BeginForm()
If you are using "multipart/form-data" that is mean you are uploading a file with your form.
You can check this out.
Ajax.BeginForm in MVC to upload files
I know that maybe the title sounds a bit weird but I believe that my problem is weird indeed. I have an ASP.NET MVC 4 application (this is my first MVC real-world application) with Razor view-engine.
I have a layout view where I'm rendering two partial views like this:
<!-- Login -->
#Html.Action("RenderLoginPopup", "Login")
<!-- Registration -->
#Html.Action("RenderRegisterPopup", "Login")
Each of those actions from the Login controller just renders a partial view:
[ChildActionOnly]
public ActionResult RenderLoginPopup()
{
return PartialView("Partial/_LoginPopupPartial");
}
Just for exemplification sake (both are built the same way), the login partial view contains an ajax form like this:
#using (Ajax.BeginForm("Login", "Login", new AjaxOptions()
{
HttpMethod = "POST",
OnSuccess = "loginResponseReceived"
}, new { #id = "loginForm" }))
The Login action from the Login controller (the target of the form) is signed with the following attributes (worth to mention and notice the HttpPost one):
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public JsonResult Login(LoginModel model)
{ }
So far, so good... Everything works perfect - both the login and the register actions are working without any issues.
The issue that I want to speak about shows-up when I have a #Html.BeginForm() in a view that is loaded along with the main layout. For example, if I have a pure and simple form like this:
#using (Html.BeginForm())
{
<input type="hidden" name="name"/>
<input type="submit" value="Send"/>
}
along with the controller CaptionExtendedController:
[HttpPost]
public ActionResult Index(string nume)
{
return View();
}
So, in the end, in my final html generated file I will have 3 forms - 2 for login and register (ajax) and one simple form generated from the last view. Please keep in mind that all three forms are independent (meaning that they are not one in another).
The issue is that everytime I'm pressing the button "Send" from the last form all controllers that are signed with the [HttpPost] attribute from my view (Login, Register from LoginController and Index from CaptionExtendedController) gets called.
WHY??? In order to have a temporary fix, I've removed the [HttpPost] attribute from the Login and Register actions and now it's working but I don't think this is correct.
Please, there is someone who can explain me why this is happening and eventually point me to the right direction in fixing this issue?
Thank you in advance.
Try specifying the controller and action with your Html.BeginForm and we can start from there. Also, you can utilize #Html.RenderPartial to render your partials which would get rid of some of your unneeded actions/controllers, making it a bit more manageable.
This doesn't address the root problem, but might be a work-around which is all you need anyway. :)
You could write some jQuery which catches the button click and then submits the form directly by name. For example, if you add the id below:
#using (Html.BeginForm())
{
<input type="hidden" name="name"/>
<input type="submit" id="regularSubmitButton" value="Send"/>
}
Then you could write:
$(document).ready(function() {
$("#regularSubmitButton").click(function(e) {
e.preventDefault();
$(this).parent("form").submit();
return false;
});
});
I'm not sure it would work without seeing everything, but seems to be worth a try.
Cheers,
Michael
It doesn't make sense anymore... Starting from the comments and answers, I've mapped 3 functions to the submits on those tricky forms: login, register and index (also I've put back the HttpPost attribute to the Login and Register actions). In those jquery functions I've just put an alert with a string (name of the form); in order to be able to write a jquery id-based selector, I've declared also the last form with an id (it didn't had it; only login and register had one), like this (an example taken from another form with the same issue):
#using (Html.BeginForm("Index", "PersonalizeCard", new {data = Model.EncryptedDataQueryStringValue}, FormMethod.Post, new {#id = "personalizeCardForm"})) { }
(what has been added - last two parameters - form method and html id).
After this, I've run the application and no exception anymore... I've put breakpoints on the login and register actions - nothing... I've even removed those 2 extra parameters from the BeginForm - still nothing...
WHY???? Again, why??? I mean, I'm not upset that it's fixed but I don't understand why it's fixed by itself...
THANK YOU FOR ALL YOUR TIME AND COMMENTS / ANSWERS.
I want to send the selected page value on the querystring while navigating through paging.
The URL that is generated for paging is like this:
Link/Index?page=2
Link/Index?page=3
But on my URL it only shows Link/Index and performs the Ajax call. But if I disable my Javascript and then navigate through paging it gets Postback and has a URL like
Link/Index?page=2
Which is perfect. But I want this type of URL in an Ajax call as well.
How can I do this? Issue is if we navigate through pages when Javascript is enable it shows Link/Index and when user goes to page no 2 then 3 then 4 and press back button it goes to press page instead of page 3 then page 2.
Here is the code that generates the page links:
<%= Ajax.Pager(
new AjaxOptions {
UpdateTargetId = "divGrid", LoadingElementId = "divLoading"
},
ViewData.Model.PageSize,
ViewData.Model.PageNumber,
ViewData.Model.TotalItemCount,
new { controller = "LinkManagement", action = "Index" }
)%>
This isn't really an issue with the pager, but that's how ajax works. Because you haven't created a new full page request, nothing is stored in history to allow the back button to persist the ajax calls too. You need to use something like jquery.history (http://tkyk.github.com/jquery-history-plugin/) or jquery address api (http://www.asual.com/jquery/address/samples/api/#/section/?id=2.2).
I have a view where I initially used Html.BeginForm(). After POSTing, I show a message with ViewData["Message"]. That works fine.
When I change to Ajax.BeginForm(), ViewData["Message"] is null.
What am I missing?
I guess when you use Html.BeginForm your controller is rendering the current View again, so the html will have the message correctly displayed.
When you make Ajax requests is up to you to control what should happen after the request success.
This can be done with the Ajax.BeginForm ajaxOptions parameter, where you can set a javascript callback function at the OnSuccess property.
FWIW, I was just plain doing this wrong. What I wanted to accomplish, and how to, is explained here - http://davidhayden.com/blog/dave/archive/2009/05/19/ASPNETMVCAjaxBeginForm.aspx
Simple enough, it would seem, but it turns out not to be - mainly due to the fact that the View can't possibly know which way through Model and Controller you got there. Regardless, it is a problem that needs a solution:
I have a login link, that takes the user to a form to enter username and password. When the user clicks "submit", I want to redirect to the page he was viewing. The easiest way to do so seems to be specifying the url to the current page as a querystring (...?returnUrl=...) and everything else is already built.
But where do I find this url from my view, when rendering the link? I naturally can't use a RedirectToActionResult as I don't want to actually transfer the user - only render the url in a link. How to?
EDIT:
I have now started a bounty on this question, and therefore I see fit to clarify my needs as well.
I have a UserControl named Login.ascx in my Shared folder. In it, I render an ActionLink to the login form, and it is included in the footer on my Masterpage. What I want to accomplish is the following:
When the ActionLink is rendered, the querystring returnUrl is appended with the a route to the view that is currently being rendered. If this is accomplished, the user will be taken back to the page he/she was viewing after successful login with functionality that is already build into the ASP.NET MVC Framework.
The reason the previous answers have not been sufficient is mainly that they have not provided a way to build the route url to the current view. I do know how to append a querystring, but I do not know how to find out what to put in that string.
In order to mark an answer as the answer, I want a method to re-construct the route to the currently shown view, from a usercontrol in the masterpage.
The solution is to use HttpContext.Current.Request.RawUrl like this:
<%= Html.ActionLink("log on", "LogIn", new { controller = "User", returnUrl = HttpContext.Current.Request.RawUrl }) %>
Or with an extension method from MVC futures (Microsoft.Web.Mvc.dll):
<%= Html.ActionLink<AccountController>(c => c.LogOn("name", "password", false, HttpContext.Current.Request.RawUrl), "login here")%>
ActionController is the default one in mvc but just add returnUrl to your own.
One way would be to build the links that send the user to the login form, with returnUrl=/PageToReturnTo (Login for example). You'd want to write it so the return url was constructed from your routes though, manually writing those links on every page could be cumbersome.
The default login action in MVC has the returnUrl functionality already built. Just need to pass it a value and it will do the rest. Here's a copy'n paste of the method signature from a fresh project.
public ActionResult Login(string username, string password, bool rememberMe, string returnUrl)
Hope that helps ya!
You can use Page.Request.Url to get the route that resulted in the currently rendered view.
Though that's more of a cosmetic detail, you might want to unify the requests that came through the '/' and '/default.aspx' routes and always return to the '/' route. I have a helper property in my master page that does exactly that.
protected Uri RouteUrl
{
get
{
if (Page.Request.Url.AbsolutePath.StartsWith("/default.aspx", StringComparison.OrdinalIgnoreCase))
{
return new Uri(Request.Url, new Uri(Response.ApplyAppPathModifier("~/")));
}
return Page.Request.Url;
}
}
I don't know about ASPX, but there are a couple of problems we encountered building this:
When the user gets their password wrong, and loops-round the Login page to have another go, the Target must still be preserved.
We also decided to preserve POST variables to a page that then required the just-in-time login