I have a cascading dropdown like for eg first dropdown shows the list of countries and based on the selection of countries the next dropdown gets populated. The problem is that in development environment it's working fine but when deployed in a server the first dropdown gets populated correctly as it's elements come from resource file and after selection of first drop down I get an error.
JS :
<script>
$(document).ready(function () {
$("#Site").change(function () {
var SelectedVal = $(this).val();
$("#Model").html('');
$("#Model").append($("<option></option>").attr("value", '')
.text(' '));
if (SelectedVal != '') {
$.get("/Home/GetModelList", { Sid: $("#Site").val() }, function (data) {
$("#Model").empty();
$("#Model").html('');
$("#Model").append($("<option></option>").attr("value", '')
.text(' '));
if (data.modelAlert != null) {
alert(data.projectAlert);
}
$.each(data.models, function (index, item) {
$("#Model").append($('<option></option>').text(item));
});
});
}
})
});
</script>
Controller :
public JsonResult GetModelList()
{
List<string> models = db.GetModels();
string modelAlert = alert.GetAlert();
var result = new { modelAlert, models };
return Json(result, JsonRequestBehavior.AllowGet);
}
The error message that I get is
Failed to load resource: the server responded with a status of 404 (Not Found) Home/GetModelList?Sid=Ind:1
I checked for similar problems like this and it was all about the JS path or the controller path but I've already given the absolute path. Can someone let me know where am I going wrong, let me know if any additional data is needed.
Thanks
$.get("/Home/GetModelList", { Sid: $("#Site").val() }, function (data) {
The above line was causing the routing problem, usually when we call a controller action from js in this way there tends to be a routing problem due to the folder structure reference. In order to avoid this routing problem and to be more clear we can also call controller action from js like below
$.get('#Url.Action("MethodName", "ControllerName")', function (data) {
This resolved my issue.
We have an instance in our application where we would like to be able to cache the results of an MVC action for multiple pages with OutputCache but what I've just realized is my basic setup caches for each page individually and thus this breaks the chain.
My ultimate goal with this is when the user hits a main page to execute an ajax request once all others are finished that loads and caches the data for subsequent pages. Then when the user navigates to another page that needs the MVC actions data it is instantly available.
This is my script to load the data asynchronously on my main page,
$(document).one("ajaxStop", function() {
$.ajax({
url: '../Companies/CompanySelectList',
type: 'GET',
success: function (data) {
//alert(data.success);
},
error: function (request, status, error) {
//alert(request.responseText);
}
})
})
And this is my MVC Action to be executed,
[OutputCache(Duration=60)]
public ActionResult CompanySelectList()
{
List<CompanyDTO> companies = new List<CompanyDTO>();
var results = _api.Companies.GetCompany();
if (results.message == null)
{
companies.AddRange(results.data);
//Build up remaining data
for (int i = results.page + 1; i <= results.totalPages; i++)
{
results = _api.Companies.GetCompany(page: i);
companies.AddRange(results.data);
}
companies = companies.OrderBy(n => n.CompanyName).ToList();
return PartialView("_CompanySelectList", companies);
}
else
{
ModelState.AddModelError("", results.message);
}
return PartialView("");
}
You could try directing the request to a web api controller, and building a simple manual caching mechanism in there.
An example can be found here: Caching in Web API
In my ASP.Net/MVC application, I am using AngularJS to display a list of records from the database. When I update a record, it doesn't get updated in the view (html) until I refresh the page?
The view:
<tr ng-repeat="bu in bus">
<td>{{bu.BU_Name}}</a></td>
<td>{{bu.BU_Info}}</a></td>
<th>Del</th>
</tr>
The JS:
$scope.editItem= function (bu) {
$http.post('/CO/DelBU', {dbunt: bu})
.then(function (response) {
$scope.bus = response.data;
})
.catch(function (e) {
console.log("error", e);
throw e;
})
.finally(function () {
console.log("This finally block");
});
};
The MVC controller:
[HttpPost]
public JsonResult DelBU(BUs dbunt)
{
var db = new scaleDBEntities();
var burecord = db.Buses.Find(dbunt.BU_ID);
db.Database.ExecuteSqlCommand("UPDATE dbo.BUs SET BU_Name='just a test'");
var burecords = db.Buses.ToList();
return Json(burecords, JsonRequestBehavior.AllowGet);
}
So, when I click on edit, the name doesn't change on the screen unless I refresh the page! How can I fix this?
Thank you
i think you need to setup a watch for bus - see here for more detail:
How do I use $scope.$watch and $scope.$apply in AngularJS?
I have built a .aspx page that calls a web api service and returns some data. The button in question is an HTML button(non .net) of type "button". I would like to save the data returned (which is a boolean) from the following jquery post:
<script>
$(document).ready(function () {
$('#custSubmit').click(function () {
var user = {
email: $('#custEmail').val(),
password: $('#custPassword').val()
};
$.post("http://blahblah", user, function (data, status) {
if (data == "true" && status == "success") {
//I imagine my save logic will go here, but I could be wrong
}
$('#custEmail').val('');
$('#custPassword').val('');
});
});
});
</script>
but I'm having trouble finding an example of how to save it to a session variable in .net. Can anyone explain to me how to do this? Thanks in advance.
I know this is duplicate but I could not get reliable solution(for asp.net web).
I just want to redirect to the login page if session expires.
I have tried following:
1. using jquery status code
$.ajax({
type: "POST",
url: "stream.asmx/SomeMethod",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
//success msg
},
error: function (request, status, error) {
if (status = 403) {
location.href = 'login.aspx';
}
}
});
Problem: this returns same status code(403) for other errors too, which I only expect for session timeout.
2. Sending json message whether session expired
code behind:
if (!object.Equals(HttpContext.Current.Session["User"], null))
{
Id = int.Parse(HttpContext.Current.Session["User"].ToString());
}
else
{
result = from row in dtscrab.AsEnumerable()
select new
{
redirectUrl = "login.aspx",
isRedirect = true
};
}
on $.ajax success:
success: function (msg) {
if (msg.d[0].isRedirect) {
window.location.href = msg.d[0].redirectUrl;
}
else {
//load containt
}
}
Problem: It's somehow desn't invoke ajax success line if session expires(it does return correct json). And even this is not a proper way if I have many number of ajax request in the page(should be handled globally).
However, I saw this post which is really good soltion but it's for mvc using AuthorizeAttribute: handling-session-timeout-in-ajax-calls
So, Is there I can use same concept used in mvc using AuthorizeAttribute in asp.net web api? If not, how I can troubleshoot those issue which I'm facing (any of above two mentioned)?
A 403 status code is going to cause jQuery to call the failure method. Keep the same code behind from your second try, but move the redirect handler to the failure method instead of the success method. In the success method, treat it as you normally would.
Problem:
I had same problem in my Razor MVC Application throwing exceptions while ajax calls made when session timed out.
The way I have managed to get this issue sorted is by monitoring each ajax requests by using a simple light weight Action Method (RAZOR MVC) returning a bool variable whether the Request is Authenticated or not. Please find the code below..
Layout/Master Page / Script file:
<script>
var AuthenticationUrl = '/Home/GetRequestAuthentication';
var RedirectUrl = '/Account/Logon';
function SetAuthenticationURL(url) {
AuthenticationUrl = url;
}
function RedirectToLoginPage() {
window.location = RedirectUrl;
}
$(document).ajaxStart(function () {
$.ajax({
url: AuthenticationUrl,
type: "GET",
success: function (result) {
if (result == false) {
alert("Your Session has expired.Please wait while redirecting you to login page.");
setTimeout('RedirectToLoginPage()', 1000);
}
},
error: function (data) { debugger; }
});
})
Then in Home Controller/Server side you need a method to verify the request and return the boolean variable..
public ActionResult GetAuthentication ( )
{
return Json(Request.IsAuthenticated, JsonRequestBehavior.AllowGet);
}
This will validate each ajax request and if the session got expired for any ajax request, it will alert the user with a message and redirect the user to the login page.
I would also suggest not to use standard Alert to Alert. User some Tool tip kind of formatted div Alerts. Standard JS Alerts might force the user to click OK before redirection.
Hope it helps.. :)
Thanks,
Riyaz
Finally, I ended up following.
public class IsAuthorizedAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
var sessions = filterContext.HttpContext.Session;
if (sessions["User"] != null)
{
return;
}
else
{
filterContext.Result = new JsonResult
{
Data = new
{
status = "401"
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
//xhr status code 401 to redirect
filterContext.HttpContext.Response.StatusCode = 401;
return;
}
}
var session = filterContext.HttpContext.Session;
if (session["User"] != null)
return;
//Redirect to login page.
var redirectTarget = new RouteValueDictionary { { "action", "LogOn" }, { "controller", "Account" } };
filterContext.Result = new RedirectToRouteResult(redirectTarget);
}
}
Handling client side
<script type="text/javascript">
$(document).ajaxComplete(
function (event, xhr, settings) {
if (xhr.status == 401) {
window.location.href = "/Account/LogOn";
}
});
</script>
you can set session time out expire warning some thing like ....
<script type="text/javascript">
//get a hold of the timers
var iddleTimeoutWarning = null;
var iddleTimeout = null;
//this function will automatically be called by ASP.NET AJAX when page is loaded and partial postbacks complete
function pageLoad() {
//clear out any old timers from previous postbacks
if (iddleTimeoutWarning != null)
clearTimeout(iddleTimeoutWarning);
if (iddleTimeout != null)
clearTimeout(iddleTimeout);
//read time from web.config
var millisecTimeOutWarning = <%= int.Parse(System.Configuration.ConfigurationManager.AppSettings["SessionTimeoutWarning"]) * 60 * 1000 %>;
var millisecTimeOut = <%= int.Parse(System.Configuration.ConfigurationManager.AppSettings["SessionTimeout"]) * 60 * 1000 %>;
//set a timeout to display warning if user has been inactive
iddleTimeoutWarning = setTimeout("DisplayIddleWarning()", millisecTimeOutWarning);
iddleTimeout = setTimeout("TimeoutPage()", millisecTimeOut);
}
function DisplayIddleWarning() {
alert("Your session is about to expire due to inactivity.");
}
function TimeoutPage() {
//refresh page for this sample, we could redirect to another page that has code to clear out session variables
location.reload();
}
4xx are HTTP error status codes and would cause jquery to execute the onFailure callback.
Also, beware of using 3xx for redirects when you want to process the payload. Internet Explorer, in my experience, just does a redirect (without looking at the payload) when a 3xx status code is returned.
I'd say, throw a 403 and handle the situation. To the client 403 implies the resource access is forbidden. There can be multiple reasons, which is OK I guess.
For those using a ScriptManager, you can easily check for ajax request and then redirect with the following code:
private void AjaxRedirect(string url)
{
Response.StatusCode = 200;
Response.RedirectLocation = url;
Response.Write("<html></html>");
Response.End();
}
Then check for request type and redirect accordingly (using routes here):
if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack)
{
var redirectUrl = RouteTable.Routes.GetVirtualPath(null, "Default", null).VirtualPath;
AjaxRedirect(redirectUrl);
}
else
{
Response.RedirectToRoute("Default");
}
The "Default" route is a route defined in the routes collection:
routes.MapPageRouteWithName("Default", "", "~/default.aspx");
If you prefer, instead of using ScriptManager for ajax request check, you can use:
if (Request.Headers["X-Requested-With"] == "XMLHttpRequest") {
code here...
}