MVC return view and navigate to page within that view - asp.net-mvc

Using C# MVC. I need to return the view if the user enters invalid information into the form.
Code is:
if (!ModelState.IsValid) {
return View();
}
But the Home view contains several pages within it that can be navigated to (#about, #services, #gallery, #contact). So once the page reloads it goes directly to the Home page (when I click Contact it navigates there and I can see the error messages) but I need it to navigate to the Contact page automatically so the user can see their error message and how to fix it.
I have tried
string url = Request.UrlReferrer.AbsolutePath+ "#contact";
return redirect(url);
This redirects the page to #contact BUT does not show the error message.
Any other suggestions, kindly assist

Related

Get URL of referring page and pass it to a hidden form field

I need to know how to get the url of the referring page of my website. When a user clicks a link to a contact form on my website (from another page on my website) how can I get the url of that page? I have tried document.referrer but it only shows the domain name of my website, I need to see what page a visitor was viewing when they clicked on the link to the contact form. My site is static html, css and javascript.
Also tried setting a cookie, but it only shows the page where the contact form is actually located, for example: www.mysite.com/contact-us.html. What I need to know is what page the visitor was viewing when they clicked on the link that brought them to the form on the contact page.
My objective is to pass the url into a hidden form field, so when submitted, I can tell which page of my website the user was viewing when they clicked on the link to the contact form. Then, if they ask a question about a specific product, I will know which page they were on when they viewed the product. Note: I have 100+ product pages that link to the contact form.
If you have a master page used by all the product pages, you can save the current url as session in master page when the product page was loaded . Then you can retrieve the session url when contact page was loaded. This should able do the work.
You can use the HttpRequest.UrlReferrer property.
Gets information about the URL of the client's previous request that linked to the current URL.
public partial class Contact : Page
{
protected void Page_Load(object sender, EventArgs e)
{
Uri urlReferrer = Request.UrlReferrer;
if (urlReferrer != null)
{
hiddenFieldUrlReferrer.Value = urlReferrer.ToString();
}
}
}

How to redirect from one action to another when action parameter are different?

I have a controller with Index and Add actions; both of which have different parameters. Index just loads the form and after form gets filled "Add" saves the entries to the database. Saving is working fine. However, when there are some error while adding, I want to show the error in the same page and stay on that page. When i retrun view it tries to render \add (ie.Add action) and it throws error as it cannot find /Add page. I am using ValidationMessage for showing error. How to redirect from one action to another when action parameter are different?
Try this:
return View("Index", model)

Managing an error in an ASP.NET MVC 4 page with multiple steps (similar to SPA)

I have an ASP.NET MVC 4 application that has one section that behaves like a SPA. It's a page with multiple steps and, because I'm working sessionless, I'm sending from the client to the server (using AJAX) the ID of the entity in every request (I'm also sending a GUID that needs to correspond to the ID in order to be valid, this is for detecting data tampering). Let's say that the user is on step 3 and one of the following things happen:
1) An error occurs: I have a global filter that inherits from HandleErrorAttribute that logs the error and sends an email, and after all, it shows a custom error page. The problem is that if the user press the browser's back button, the hidden fields are lost and the process has to start from step 1 again.
2) The user navigates away from the page. I think that I can warn the user with a dialog.
Thanks in advance.
EDIT:
I'm showing a warning dialog when the user wants to navigate away.
$(window).bind('beforeunload', function () {
if ($("#id").val() != "") {
return 'If you leave the page, the offer will be lost.';
}
});
If after he navigates away presses the browser's back button, I'm redirecting him to the first step of the flow because the previous entered data is lost.
if ($("#id").val() == "" && window.location.hash != "") {
window.location.hash = "";
}
It sounds like your AJAX request for the next step is hitting a Controller action that's redirecting you to a new page. That's fine, and it's good you're keeping your server code stateless by sending up all the relevant information back up to the Controller for each step. However, doing it this way means that you're stuck using the custom error page, and you're going to have trouble making that work well with your setup.
My suggestion: move more towards a true SPA. When I visit Step1, the Controller should send back a whole page (like you're doing). Let's assume that this page has a container like <div id="step-container"> ... HTML for each step is in here ... </div>.
Now, when you click the button to move on to step 2, instead of hitting the controller action expecting to get redirected to a new page, send out an AJAX request for a Partial View with the Step 2 content.
On the server, change your Step2.cshtml from a regular view to a Partial View (you can make a new View and click the Partial View checkbox), and for convention's sake, you should probably rename it _Step2.cshtml. In your Controller action public ActionResult Step2(... data), you could change your return statement to return PartialView("_Step2"), but leaving it as return View("_Step2") is just fine.
Now for the important part, the client. Here, you're issuing an AJAX request for that Partial View.
// Set the data from your form in this variable
var data = { };
// Issue a GET request out to the controller action. Make sure the URL is right
$.get('/Steps/Step2', data)
.done(function(result) {
// This promise will execute when we get the content of the Partial View back from the server
// The result variable should have the HTML for the view
// Use jQuery to set the content in your step div to the new HTML
$('#step-container').html(result);
})
.fail(function(error) {
// This promise function will execute if there is an error in the Controller
// and it returns something other than a 200 type response code
// Handle the error here, maybe showing a dialog or trying to fix the error
alert('Sorry, form submission failed');
});

Changing the Url after RedirectToAction

I have a form on my index view that is posting to my submit action
like this
#using(Html.BeginForm("Submit","Receiving", FormMethod.Post))
{
....
}
In that action I am returning a RedirectToAction after all the work that is needed is done
public ActionResult Submit(string selectedSerialNumber, string aisle, string rack, string rackbin)
{
//do the work
return RedirectToAction("Index");
}
after the user submits the form the Url shows "/Receiving/Submit" with the view of the index
instead of
"/Receiving"
or
"/Receiving/Index"
If the user refreshes the page it tries to go back to the submit action again which is not what is expected and causing problems. they are expecting to refresh the index page
how can I get that Url to go back to the index action after it is redirected.
Thanks!
Jquery mobile is the cause I found this question after i realized the only difference with this site is jquery mob

How to create a view that is not accessible directly but can only be redirected to?

I'm currently working on the user registration in my project. After the registration is done I wish to show some confirmation to the user. I decided to create another view. That's fine.
Now, if after the registration I just return the view like:
public class MyController : Controller
{
[AcceptVerbs (HttpVerbs.Post), ValidateAntiForgeryToken]
public ActionResult Registration (FormCollection form)
{
/* Some logic goes here */
return View ("ConfirmationView");
}
}
Everything is working as desired. No changed url in the title bar. But... If I click the refresh button, the browser will submit the data from the form again which I do not want.
Then I decided to create a separate action, but that means it will produce a new url in the address bar. I do not want the user to click refresh now because this view will not be able to sensibly display the confirmation information again. Is there any way to make an action not accessible directly? Or at least any way to determine whether it was called directly or by redirection? In the latter case I would just take the user away from that page to maybe the home page.
Any way to accomplish this?
So I found the solution myself.
One can use TempData to detect the repeated or external action calls.
public class MyController : Controller
{
[AcceptVerbs (HttpVerbs.Post), ValidateAntiForgeryToken]
public ActionResult Registration (FormCollection form)
{
/* Some logic goes here */
TempData["RedirectCall"] = true;
return RedirectToAction ("Confirmation");
}
[AcceptVerbs (HttpVerbs.Get)]
public ActionResult Confirmation ()
{
if (TempData["RedirectCall"] == null)
return RedirectToAction ("StartPage", "Home");
return View ();
}
}
Nice and simple. :)
One way to solve your problem is to attach a guid or similar type of "random" data to a user session, and check for a valid session when the page is requested. If there is none, you redirect to a page saying that this url is not available at the moment, and that the user will soon be redirected (and then redirect to home after 5 seconds or so using js).
Roughly it would work like this:
When the user is registered, a session cookie is created with for example a GUID. The GUID is also stored in a database table, in which you have one column for the UserID primary key and one for the GUID. You also create an authentication cookie, thus logging the user on to your site.
When all datacalls etc are done, the user has been successfully registered and so on, you redirect to the confirmation page.
When the confirmation page is loaded, the user is automatically logged on (because you created the authentication cookie in step 1). You can then check for a row in the UserID-GUID table corresponding to the logged on user.
a) If there is such a row, you delete the row, and display the confirmation page with all the information.
b) If there is no such row, you display the error message and redirect. As you deleted the row when you showed the message the first time, the user will not be able to access the confirmation page again.
Note: If you use this approach (or some other that makes the confirmation page available only once) you should make sure that it is clearly stated on the confirmation page that the user won't be able to access that page again.
if(Request.UrlReferrer == null)
{
return RedirectToAction("Index");
}

Resources