AJAX not working on MVC Page - asp.net-mvc-3

I am using MVC3 with Razor. I have one Action which want to load using AJAX. I am using jQuery UIblock plugin http://jquery.malsup.com/block/# to show some wait image to user.
The View corresponding to action is as shown below:
#using (Ajax.BeginForm("Search", "Home", new AjaxOptions() { HttpMethod = "GET", OnBegin = "BlockUI", OnComplete = "UnBlockUI", UpdateTargetId = "page" }))
{
...................
}
Javascript code is as shown below:
<script type="text/javascript">
function BlockUI() {
$.blockUI({ message: "<img src='#Url.Content("~/Content/images/loading.gif")' />" });
}
function UnBlockUI() {
$.unblockUI({ message: "Done....." });
}
Now I am redirecting to Action using a link as
location.href = '#Url.Content("~/Home/Search/")';
When the search view is loading, I cannot see any Div showing Loading image.
The same thing is working on other page, the only difference is that on other pages the Image is coming on POSTBACK.
Additionally, all Ajax POST operations are working but not GET ones.
What is the problem with Search page here ??
Thanks.

Now I am redirecting to Action using a link as
location.href = '#Url.Content("~/Home/Search/")';
The keyword here is I am redirecting. It's not I am sending an AJAX request. When you redirect, the browser simply stops running any scripts on the current page and redirects away to the target location. The OnBegin and OnComplete methods that you have subscribed to will never fire when you redirect which is why you are not seeing any blockUI.

Related

CORS error when trying to redirect user from a partial view

I am working on an application written in ASP.NET MVC5 which require the user to be log in. The authentication works with Central Authentication Service (CAS). On the homepage, I have several partial views :
Home page with partial views
I call a controller's action when I want to update the user's data.
It's working well, until the CAS session expires. If I try to refresh the partial views, I get an error :
"OPTIONS https://example.com/CAS/Authentication 403 (Forbidden)"
"Failed to load https://example.com/CAS/Authentication: Response for preflight has invalid HTTP status code 403"
I think it comes from the use of Ajax to refresh the partial view and it returns me the login page, which is not on the same domain. How can I overcome this issue ?
In my View I send the datas to the Controller with Ajax.BeginForm() and my controller returns a partial view, so that I don't need to completely refresh the page.
To overcome the Cross Origin Request error, I needed to handle the Ajax response. Instead of letting the login page being returned in the partial view, I call a Javascript function on the OnComplete event, checking the status code of the response.
In my partial view :
AjaxOptions ajaxOptions = new AjaxOptions
{
HttpMethod = "POST",
OnComplete = "redirectToLoginPage"
};
using (Ajax.BeginForm("ActionName", "ControllerName", null, ajaxOptions))
{
<button type="submit">Submit</button>
}
On click on submit, it will execute the action "ActionName" from the controller "ControllerName". Then, it will fire the Javascript function "redirectToLoginPage", which is :
function redirectToLoginPage(xhr) {
if (xhr.status == 200) {
//Whatever
}
else
{
window.location.replace("https://login.example/");
}
}
This do the trick.

Spring-Boot: Redirect and Refresh model and page

I have a spring-boot application, with theyemleaf. I repeatedly update the page, and redirect it to the same page, so i expect that the elements of the page get updated:
#GetMapping("/suggested-events/vote/{eventId}")
public String voteForEvents(Model model,
#PathVariable("eventId") Long eventId,
#RequestParam(value = "message", required = false) String message ) {
log.info("The message is: "+message);
SuggestedEvent event = suggestedEventService.findSuggestedEventById(eventId);
ArrayList<SuggestedEvent> events = suggestedEventService.findSuggestedEventsByArea(event.getArea());
model.addAttribute("mainEvent",event);
model.addAttribute("events",events);
model.addAttribute("message",message);
return "/suggested-event/vote";
}
and when a button get pushed in the view it triggers the below post method:
#PostMapping("/suggested-events/vote")
public String voteForASuggestedEvent(RedirectAttributes redirectAttributes){
log.info("You have made a vote");
redirectAttributes.addAttribute("message", "Success");
return "redirect:/suggested-events/vote/1";
}
This second controller method, performs an operation an makes a message, and redirects it to the first method. So, it successfully redirected to the first method and it logs
log.info("The message is: "+message);
but it does not refresh my page, and i do not get the message as model?
When i redirect to the first method, i expect it adds the message to my models:
model.addAttribute("message",message);
But it does not added to my page
and when a button get pushed in the view it triggers the below post
method:
It sounds like this trigger is using AJAX, rather than a form submit. Doing so would match the symptoms you describe.
If you POST to /suggested-events/vote using AJAX, the server will return a 302, and the browser will follow it. However, the response for that 302 is still the result of an AJAX call. You have access to it in your success callback, but the browser isn't going to render it for you.
but it does not refresh my page
If a 302 doesn't cause your page to re-render, this also suggests you're using AJAX.
If you actually use a form submit instead, the browser will re-render using the markup returned by the successful redirect.
This can be verified by using the following two buttons in your vote.html:
<form action="http://localhost:8080/suggested-events/vote" method="POST">
<input type="submit" text="Submit" />
</form>
<button onclick="postmessage();" >Button</button>
<script>
function postmessage() {
$.ajax({
method: 'POST',
data: {},
url: 'http://localhost:8080/suggested-events/vote'
});
}
</script>
The first button will work as expected, and the second button matches the symptoms you describe.
If you are already using a form, please update the question with it (or better yet, the entire Thymeleaf template).
I had the same problem as OP described and Mike's explanation brought me in the right direction.
I am reading a db-table and populating it with thymeleaf using th:each. I wanted to add a javascript-confirmation before deleting an item. Sending an ajax GET without an event-listener and reloading with location.reload(true) didn't reach the #GetMapping("/delete/{id}") in the controller.
This SO-thread gave me the answer to the ajax-call.
<a class="btn btn-danger" href="#" th:onclick="|confirmDeletion('${u.id}')|"></a>
<script th:inline="javascript">
function confirmDeletion(id) {
if (confirm("Delete this id? " + id)) {
var http = new XMLHttpRequest();
http.open("GET", "/delete/" + id, true);
http.addEventListener("readystatechange", function() {
if (http.readyState === 4 && http.status === 200) {
window.location.reload(true);
}
});
http.send();
}
}
</script>
there are many ways to redirect page in Spring, but be sure if the model attribute off message its passing correctly to FrontEnd or passing like parameter to another handler , you can see this document : http://javainsimpleway.com/spring-mvc-redirecting-model-attributes-from-one-controller-to-other-controller/ , hope this is useful !!

Parital view show login page with fullsite if session out after computer left idle for long time

I have created an asp.net mvc razor application, in which I load a partial view in a div, which can be accessed after login.
<% using (Ajax.BeginForm("Showproducts", "Home", new AjaxOptions {
UpdateTargetId = "resdiv", OnBegin = "fstart()", OnSuccess = "fend()"
}, new { id = "_myform" }))
{ %>
.....
<% } %>
When a user leaves their computer for a long time (which makes the session time out automatically) and then clicks the submit button, the resdiv is filled with the full site with the login panel. I want to show the full site with login panel NOT in the resdiv. Is there any way to avoid this behavior?
Is there any way to avoid this behavior?
Yes, there is a way. I would recommend you reading the following blog post in which Phil Haack illustrates a very nice technique allowing you to override the Forms Authentication Module for AJAX requests and be able to send a 401 status code instead of redirecting to the login page.
Then on the client side you could use a global AJAX handler where you could test the status code and if it is 401 redirect to the logon page.
For example once you have installed the AspNetHaack NuGet you could add the following global error handler to your view:
<script type="text/javascript">
$(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) {
if (jqXHR.status == 401) {
// not authenticated => redirect to login page:
window.location.href = '#FormsAuthentication.LoginUrl';
}
});
</script>

Fanycbox 1.3.4 ajax issue with ASP.NET MVC

I'm using Fancybox 1.3.4 with ASP.NET MVC 3.
I have following link :
<a id="various" href="Like/List/#feed.Id" class="petlikeCount liked">#feed.LikeCount</a>
and also jquery :
<script type="text/javascript">
$(document).ready(function () {
$("#various").fancybox({
type: 'ajax'
});
});
</script>
Controller action in Like controller :
public JsonResult List(int id)
{
return Json("success", JsonRequestBehavior.AllowGet);
}
My problem is that Like/List is never called (checked with the breakpoint) and fancybox just appears and show content of "parent" page....
I also tried with iframe content returning pure html back, but I'm getting same strange behavior as above.
Thank you in advance!
I'd recommend you using HTML helpers instead of hardcoding anchors:
#Html.ActionLink(
feed.LikeCount,
"List",
"Like",
new { id = feed.Id },
new { id = "various", #class = "petlikeCount liked" }
)
Another thing that you should make sure is that the feed.Id is actually an integer variable so that when the List action is invoked it is correctly passed this id.
So your url should look something like this: /List/Like/123. And then assuming tat you have kept the default route and haven't messed up with some custom routes, the List action should be called and passed the correct id as argument.
Also I would very strongly recommend you using a javascript debugging tool in your browser such as FireBug in which you will be able to see any potential errors with your scripts as well as the actual AJAX requests being sent which will allow you to more easily debug such problems.

How to show the ajax loader image while remote validating using data annotation in asp.net mvc3

in my asp.net mvc3 application i am doing remote validation if a user already exist using data annotation . it is working perfectly . i was wondering if there is any why i can show the ajax loader image beside the input field in the form while remote validation(ajax request) is taking place.
please help me
Thanks
I don't think you can do it without writing the validation code yourself.
See this article:
http://www.highoncoding.com/Articles/767_Remote_Validation_in_ASP_NET_MVC_3.aspx
Within the AJAX call you would have to add a beforeSend to display the image, then hide it on complete.
You can use $.ajaxStart .ajaxStop for this purpose:
$("#yourRegisterFormToValidate")
.ajaxStart(function () { $(".loader").show(); })
.ajaxStop (function () { $(".loader").hide(); });
If that was me, I would want to stop user from entering data into any other fields until this is validated, therefore I would use AjaxOptions to specify animation and duration of that animation.
I'd have something on the lines of:
#{
AjaxOptions ajaxOpts = new AjaxOptions
{
UpdateTargetId = "updateDiv",
LoadingElementId = "myImg",
LoadingElementDuration = 2000,
HttpMethod = "GET"
};
}

Resources