How to reduce/eliminate wait time/latency in AJAX request - ajax

I have a ASP.NET MVC3 project where the main aspx page is doing a dynamic loading for its parts using jQuery ajax. So basically when the site loads, it hits /Home/Index and then within Index (aspx) view, there are several lines of jQuery that make ajax calls (to /Home/PartOne and /Home/PartTwo to populate parts of the page.
So every time the page loads, it basically is doing 3 requests: to get index, to get PartOne, and then PartTwo.
The question: Why is there some kind of "wait" time for the the third request to execute? I thought this was the browser concurrent request limit, but why isn't it executing after the 1st request is done?
When I experimentally put "OutputCache" attribute on "PartTwo", it behaves as expected, that it was executing fast. This hints that the problem is not in IIS, but somewhere after that and before it hits my action method.
Here is a screen shot from Chrome network profiler:
Here is a screen shot on the MvcMiniProfiler - look at the 3rd row/value, it is waiting for 500ms before executing my controller's action code.
My controller code looks like this. Although I snipped the actual code, but code for PartTwo is very trivial (no long computation, no db calls, etc):
public class HomeController : Controller {
public ActionResult Index() {
// do something here
return View();
}
public ActionResult PartOne() {
// do something here
return View();
}
public ActionResult PartTwo() {
// do something here
return View();
}
}
My javascript:
$(document).ready(function () {
$.ajax({
url: "/Home/PartOne",
cache: false,
success: function (data, textStatus, request) {
$("#TestContainerOne").html(data);
}
});
$.ajax({
url: "/Home/PartTwo",
cache: false,
success: function (data, textStatus, request) {
$("#TestContainerTwo").html(data);
}
});
});
My index.aspx:
<h2>Home page</h2>
<div id="TestContainerOne"></div>
<div id="TestContainerTwo"></div>
PartOne.ascx:
<h2>Part One</h2>
PartTwo.ascx:
<h2>Part Two</h2>
Help?

You should use read only session state or disable it completely in order to get parallel processing of Ajax requests. By default the server locks the session state for requests coming from the same client, so the requests are executed sequential.
This is done by decorating your controller with the SessionState attribute:
[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
public class HomeController : Controller {
public ActionResult Index() {
// do something here
return View();
}
public ActionResult PartOne() {
// do something here
return View();
}
public ActionResult PartTwo() {
// do something here
return View();
}
}

Related

Redirection in ASP.NET MVC to a controller method after the post AJAX call

Present set up -
url: configMap.sitePath + "api/Quiz/" + quizResponse.quizId,
data: JSON.stringify(quizResponse),
success: function (data) {
// Display the data on UI
}
the above post is to a .NET api controller which returns quizResponse.
[ValidateModelState, HttpPost]
public HttpResponseMessage Post(int id, QuizResponse value)
Now as per a new requirement , Once the api has the response I should redirect to another page(a MVC controller and then view). How do I achieve this -
public ActionResult ScptResult()
{
return View();
}
I also thought of redirect after ajax success but not sure if its a correct way.
Also, How do I pass data to the scptresult controller method after post?
In the success function of your JQuery, redirect the page to your MVC page:
window.location = '{controller}/{action}/{quizid}';
Assuming you use the standard MVC routing, and assuming you change your ScptResult function to accept a parameter, so you can pass data to it.
public ActionResult ScptResult(int quizid)
{
return View();
}
Use in java-script after complete your work in success method or anywhere
window.location = '#Url.Action("ScptResult", "YourControllerName")';
I should warn, I'm not very familiar with ajax responses but hopefully this gets close.
API
[ValidateModelState, HttpPost]
public HttpResponseMessage Post(int id, QuizResponse value)
{
//Other stuff...
var redirect = string.Format(#"/controller/ScptResult/{0}", id);
return new HttpResponseMessage()
{
Content = new StringContent(redirect)
};
}
Javascript
url: configMap.sitePath + "api/Quiz/" + quizResponse.quizId,
data: JSON.stringify(quizResponse),
success: function (data) {
window.location = data;
}
Controller
// This follows the default route.
// "/{controller}/{action}/{id}" where id is optional.
// window.location = "/ControllerName/ScptResult/OtherData"
public ActionResult ScptResult(string id)
{
return View();
}

Which one is better? Ajax post or page post[Controller httppost] when only one form is there in a page?

I have a page called Bookprogram which contains 6 input controls namely, txtName, txtEmail, txtPhone, selectcat[dropdown for categories], txtDate, txtMessage. Now when am done with all the validations for the above control, I want to store the data in db. I know how to perform both in ajax as well as complete page posting.
If it's in ajax, after validations, I would just call $.ajax and post the data as a string and fetch it in controller as below:
[HttpPost]
public JsonResult BookProgram(string name, string email, string phone, string category, string date, string message)
{
//code to save into db
return Json(result);
}
If I have to post a whole page, after validations I would just do a $(form).submit(); and write as below in controller:
[HttpPost]
public ActionResult Bookprogram(Mymodel model)
{
//Code to save the data
return View();
}
I just want to know which is better, safe and good to use as I have to display a message after successful submission. I know I can take either of the ways to display message but Is postback[page refresh] really needed in this scenario and if yes what are the advantages of it over ajax post?
EDIT :
I just went through this link and tried to implement 2nd solution of highest voted answer but for my bad luck it wasn't hitting the controller itself. I have kept breakpoint in my controller.
$(form).on("submit", function (e) {
e.preventDefault();
ValidateForm(form);
var selectedVal = $(form).find('select').children(":selected").val();
if(selectedVal=="")
{
$(form).find('div.bootstrap-select').children(":first").addClass('alert-danger');
$(form).find('div.bootstrap-select').next('.text-danger').html('Please select a category!');
}
var formContainer = $(form + ' .text-danger');
if ($(formContainer).text().length == 0) {
$.ajax({
url: '/Home/BookProgram/',
type: "POST",
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: $('#fbookprogram').serializeArray(),
success: function (data) {
if (data.result == "Success") {
alert('success');
}
else {
alert('fail');
return false;
}
return true;
}
});
}
$(form).unbind('submit');
return false;
});
Controller :
public ActionResult BookProgram(MyModel model)
{
if(ModelState.IsValid)
{
//code to save data
}
return Json(new { success = false });
}
What is that I am missing here.
Post Back
Browser Handling - The only advantage I can think of is that the browser will handle redirects and progress loading for you. You don't need to write the logic to redirect users or show a loading bar.
AJAX
Asynsconous -
With AJAX you're getting asyncronous calls so the browsers thread isn't blocked. This allows the user to still interact with the UI whilst waiting for the response from your request.
Better Performance -You generally don't need to reload the entire page resulting in less overhead & HTTP requests being made.
FYI - You can still model bind with JsonResult
public JsonResult BookProgram(Mymodel model)
{
//code to save into db
return Json(result);
}
Post back - is a classic workflow. Delegate most of inner work to your webbrowser. All your responce logic calculated on server side.
AJAX - is a modern way of building dynamic web-applications. Base approach for single-page-applications. Most of work in this case should be done on client side.

Mvc Ajax Jquery Not refreshing view on post

I am new to ajax and mvc... i have a problem with posting back data from jquery. The problem I have is the values are being populated the controller is hit database is updated and then it returns to the page with old data it is not refreshing I have to click f5 to see changes what am I doing wrong? Thanks in advance
Jquery
var values =
{
"PagePartIdentifier": element,
"PagePartContent": data
}
$.post(#Html.Raw(Json.Encode(Url.Action("UploadData", "Home"))),values,function(data)
{
// do stuff;
});
Model
public class PagePartModel
{
public string PagePartIdentifier { get; set; }
public string PagePartContent { get; set; }
}
Controller
[HttpPost, ValidateInput(false)]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult UploadData(PagePartModel pagePartm)
{
UpdatePage(pagePartm);
ModelState.Clear();
//return RedirectToAction("Index");
return Json(new { success = true });
}
Html is rendered from a helper method
public static PagePartModel PageAfterContent(this System.Web.Mvc.HtmlHelper html, int page)
{
string part = "AfterContent";
Blog.PageParts pageParts = new Blog.PageParts();
PagePartModel thispart = pageParts.GetContentForPageByPart(page, part);
return thispart;
}
Returns the model for each part to the page
When using $.post, you're sending the data to the server via ajax, so the page never reloads. I'm not sure what the UpdatePage(pagePartm); call in your post method is doing, but since that method is getting called with ajax, it can't change anything on the page. Now in your success handler on your $.post, you can manipulate the DOM to reflect the success or failure of your $.post call.
In your action, instead of returning your Json(new { success = true }); you should/could return the data that you want to be displayed on the page,
e.g.
return Json(new { pagePartm }); // if that is what should be returned
Then modify your $.post() to append the data into the DOM somewhere.
e.g.
$.post("your_controller_action", { name: "John", time: "2pm" },
function(data){
doStuff(data); // this is your point of interaction with the returned data
// or
$("#my_h3").val(data.pagePartm.PagePartIdentifier);
$("#my_div").append(data.pagePartm.PagePartContent);
});
from the jQuery.post documentation.
This will avoid the need to refresh the page to see the results.
jquery ajax post cache property is false ?
$.ajax({
url: '/youraction',
cache: false,
type: 'post'
success: function (data) {
},
error: function (e) {
alert(e.responseText);
}
});

ASP.NET MVC "Ajax.BeginForm" executes OnSuccess even though model is not valid

I have a "submit feedback" form which uses "Ajax.BeginForm" to render a partial containing the form elements. The OnSuccess event is triggering even if the ModelState is not valid. Is this normal? I was expecting to be able to do a few postbacks resulting in an invalid model, then when the model is valid and there are no errors then the OnSuccess event would trigger?
I handle this issue with a fairly simple javascript technique:
First setup your OnSuccess like this:
OnSuccess = "UpdateSuccessful(data)"
Then your javascript function like this:
function UpdateSuccessful(data) {
if (data.indexOf("field-validation-error") > -1) return;
// Do your valid stuff here
}
This way, there is no need to mess with your controller, or more importantly, your controller can return the Partial View with the model errors without doing anything weird, ie:
public ActionResult SaveDetails(Project model)
{
if (ModelState.IsValid)
{
model.SaveProject();
}
return PartialView("ProjectForm", model);
}
And in your AjaxOptions:
UpdateTargetId = "FormContents"
Now just make sure you have a div or something with id="FormContents" wherever you want your form displayed.
Is this normal?
Yes, of course. If the server sends HTTP 200 the OnSuccess method is called. The notion of modelstate validity is server side only. As long as your controller action returns some view/partial/json/... the OnSuccess will trigger. If an exception is thrown inside your controller action then the OnError will be triggered instead of OnSuccess.
So in order to handle this case you could have your controller action do something along the lines of:
[HttpPost]
public ActionResult Process(MyViewModel model)
{
if (!ModelState.IsValid)
{
return Json(new { success = false });
}
return Json(new { success = true });
}
and then:
function success(result) {
if (result.success) {
// the model was valid
} else {
// the model was invalid
}
}
Now in the case of invalid model you might want to show the error messages to the user by refreshing the form. What you could do in this case is place your form inside a partial and in the event of an invalid modelstate you would return a partialview from your controller action and in the case of success a json object. So in your success handler you could test:
function success(result) {
if (result.success) {
// the model was valid
} else {
// there were errors => show them
$('#myform_container').html(result);
// if you are using client side validation you might also need
// to take a look at the following article
// http://weblogs.asp.net/imranbaloch/archive/2011/03/05/unobtrusive-client-side-validation-with-dynamic-contents-in-asp-net-mvc.aspx
// and reattach the client validators to the form as you are
// refreshing its DOM contents here
}
}
You can do the following:
var OnSuccess = function() {
if ($(".validation-summary-errors").length == 0) {
//Your javascript/jquery code goes here
}
}
Slight variation on Luis' answer:
function OnSuccess() {
if ($("span[class='field-validation-error']").length == 0) {
alert("Target Platform saved Successfully.");
}
}
I return a bad request instead of the View to ensure that the ajax call returns onfail and not onsuccess.
In the xhr.statustext you can find the string written in the bad request and manage correctly the onfail event.
Server side:
if (!ModelState.IsValid)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Model not valid");
}
Client side:
$.ajax({
url: '',
method: 'POST'
}).fail(function (xhr) {
alert(xhr.statustext);
});

Load MVC PartialView via Ajax

In my View I have:
$.ajax({
url: '/Profile/TryToGetPersonalInfo',
type: 'post',
success: function (outData) {
if (outData.loggedIn == true) {
$('#PersonalInfoData').load(outData.data);
}
}
});
And in my Controller I have:
[HttpGet]
private ActionResult PersonalInfo()
{
return PartialView();
}
[HttpPost]
public JsonResult TryToGetPersonalInfo()
{
// loggedIn is temporary
return Json( new { loggedIn = true, data = this.PersonalInfo() } );
}
How come .load() doesn't do the job? I have also tried .html(), but still, no luck.
Please note that I really want to keep this form (having ProfileInfo() as private), and TryToGetProfileInfo() as post, cause I'm using validation tokens.
You are returning a Json object. You need to return html. In similar cases, I declare the action return type as an ActionResult and return a partial view.

Resources