I am building a solution using asp.net MVC and it is my first time doing so.
The problem
After the solution has been running for some time the controllers become unresponsive. The client side works fine, and when calling a controller using ajax, the controller begins excecuting, but whenever it hits the first line it stops excecution. The ajax call is still waiting for a responce, and I am able to make a new request (that also stops). It does not throw any errors, it just stalls. This happens both when debugging or "start-without-debugging".
Entity framework is used within some of these controller methods for database calls, if it has anything to do with the error.
I am suspecting that one of these things must be done, but I am not certain at all:
Is this only an issue because I am using localhost?
Are there some settings describing maximal runtime? Is there a specific thing
I must do whenever a controller is called?
Does the database has anything to do with the stalling?
I am not sure what code to attach, since this error seems to happen after some time, and not specific to a controller or method. Let me know if there is something you want to see.
Edit
I'm adding one ajax call as example, but note that the ajax call is working. It is the controllers (Not only RemoveTest-controller) that stalls and only after debugging for some time.
$.ajax({
type: "POST",
url: "/RemoveTest/RemoveByPlacement",
data: { input: someInput},
dataType: "json",
success: function (data) {
alert(data);
},
error: function () {
alert("Error");
}
});
Edit 2
I should maybe say that it is not only happening when using ajax. The problem also happens when opening a new page, since this also needs execution from a controller.
UPDATE
This may be an issue with the database. I have inserted var a = 10; to my controller, and this is getting executed. But it stops after trying to execute the line after.
[HttpPost]
public JsonResult RemoveById(string id)
{
var a = 10;
TestReciving test = db.TestRecevings.FirstOrDefault(x => x.Id == id);
Placement placement = db.Placements.FirstOrDefault(x => x.TestRecivingIdRef == id);
...
}
UPDATE
I did what Mark Homer said. Even though this had to be fixed, it did not solve my problem. When running in IE I get a HTML1300 (navigation occurred) message when changing page, but when it halts and I try to open the file I get "http://localhost:51140/Account/Login could not be opened". It seems to me that IIS Express stops responding, even though it keeps running.
The controller looks like this now:
[HttpPost]
public JsonResult RemoveById(string id)
{
using (var db = new DatabaseContext())
{
TestReciving test = db.TestRecevings.FirstOrDefault(x => x.Id == id);
Placement placement = db.Placements.FirstOrDefault(x => x.TestRecivingIdRef == id);
...
}
}
So I finally got it to work. The issue was a two-headed giant which was why I had troubles pinning it down.
First issue
Mark Homer said to use using when I used the database. I did this and while it solved a subset of the issue, it did not solve it completely. But from this day I will remember to use using.
Second issue
I was not able to track it down to something specific, but I created a new project and moved my files into it (except the auto generated once). Since doing this have have not been able to reproduce the problem. I tried using GitHub to find differences in the two solutions, but only to find that the non-working project had different framework versions. It really bugs me, that I can not pin down the reason, but at least it works.
Thanks for your responses, guys.
Related
I have been searching for a solution this problem for quite some time, including browsing the message board here. To start off, I will refer to an existing post:
I have used the most popular solution, and the controller successfully runs the query:
[HttpGet]
public ActionResult LoadBidders(int Id)
{
List<tblWinLossBidderMap> bidders = _context.tblWinLossBidderMaps.Where(p => p.WinLossID == Id).ToList();
return PartialView("_WinLossBidderView", bidders);
}
The Javascript
$(document).ready(function () {
$("#pY").on("click", function () {
var temp = $("#WinLossID").val();
$.ajax({
url: "/WinLoss/LoadBidders",
type: "GET",
data: { Id: temp }
})
.done(function(partialViewResult) {
$("#BidderCompany").html(partialViewResult);
});
});
});
The problem I have is that when the controller exits, back into the Javascript, I get an exception "Microsoft.CSharp.RuntimeBinder.RuntimeBinderException", "Cannot convert null to 'bool' because it is a non-nullable type value".
Note that the partial view uses a foreach to display the data. Ideally, once this is working, I will take the code snippet and append it after another jquery function that actually adds to this list. The effect is the user would fill in part of a larger form (like master/detail), click a button, a record would be added, and then this routine would update the partial view with the updated information. I doubt this part is important, but just including it for completeness.
Is there some something missing from my code?
Note that I am using Visual Studio 2015.
I have a (working) MVC-application that uses Session properties on multiple parts:
return httpContext.Session[SPContextKey] as SharePointAcsContext;
(ignore that this is sharepoint; This problem isn't be SP-specific)
This works fine until I try to enable Outputcaching:
[OutputCache (Duration =600)]
public ActionResult Select() {
DoSelect();
}
When the content is cached, httpContext.Session becomes NULL.
Is there a way to keep the Session data and also use caching?
I found the solution myself. It took a while until I came to the conclusion that - if the data is cached - there shouldn't be any individual code at all that is run. Cause that should be the main purpose of the cache: Don't run any code when the data is cashed.
That led me to the conclusion that the code causing the problem must be run before the cache. And so the "bad boy" was easy to find. Another attribute (in this case an AuthorizeAttribute) that is before the OutputCache-Attribute in the code is still run when caching applies but cannot access the Session:
[Route("{id}")]
[UserAuth(Roles =Directory.GroupUser)]
[JsonException]
[OutputCache(Duration = 600)]
public ActionResult Select()
{
DoSelect();
}
Putting the UserAuth-Attribute BELOW the OutputCache-Attribute solved the problem
Ok, it's quite late here and I may be missing something stupidly obvious but as it stands the error I am receiving (below) makes absolutely no sense.
I currently have the below C# code in two separate controllers, fundamentally the results returned in one of the JsonResults will be different but for now I copied the code to rule out an underlying issue.
public JsonResult GetProducts(DataTableParameters param)
{
var products = _productsRepository.GetAll().ToList();
var totalRecords = products.Count();
var filteredUsers = totalRecords;
if (!string.IsNullOrEmpty(param.sSearch))
{
products =
products.Where(w => w.ProductName.Contains(param.sSearch) ||
w.Description.Contains(param.sSearch)).ToList();
filteredUsers = products.Count();
}
var productList = products.Select(product => new[] {
Url.Action("Details", "ProductAdminstration", new {id = product.ProductId}),
product.Description,
product.Price.ToString(),
string.Empty,
product.ProductName,
Url.Action("Edit", "ProductAdminstration", new { id = product.ProductId }),
Url.Action("Delete", "ProductAdminstration", new { id = product.ProductId })
});
var parms = new
{
sEcho = param.sEcho,
iTotalRecords = totalRecords,
iTotalDisplayRecords = filteredUsers,
aaData = productList
};
return Json(parms, JsonRequestBehavior.AllowGet);
}
The above code works in the Index view of the ProductAdminstration controller, the datatables renders the data as anticipated using the below JQuery and obviously a table rendered in the HTML with the appropriate ID.
oTable = $("#products").dataTable({
"oLanguage": {
"sEmptyTable": "No results available",
"sSearch": "Search",
"sLengthMenu": "Show _MENU_",
"sProcessing": "Processing" },
"bServerSide": true,
"sAjaxSource": "#Url.Action("GetProducts", "ProductAdminstration")",
"bProcessing": true,
"aoColumns": [
//RENDER COLUMNS HERE
]}).fnSetFilteringDelay(500);
However, if I copy the above code from ProductAdminstration (JQuery and JsonResult) to another controller (Ordering) and change sAjaxSource to point at the new controller the below error gets thrown:
0x800a139e - JavaScript runtime error: DataTables warning: table id=products - Invalid
JSON response.
Baring in mind, the only thing I've changed is the controller name in sAjaxSource and if I change the controller name back to ProductAdminstration instead of Ordering everything works perfectly normal.
Both controllers require the user to be authenticated, however, I've removed my custom handler off the Ordering controller to rule out any issues. I've had a look around for the above error, and although there is a lot of information on the subject it doesn't seem to explain what is causing this problem when in one scenario it works perfectly fine, but in the other it doesn't.
Edit:
If it helps anyone, I cannot even type in the URL manually to get the JSON result from http://localhost:50210/Ordering/GetProducts (I'm not working with a live server yet so I cannot point you to a live URL). It renders the page then throws a hissy fit, instead of doing a download.
So, I came back to the code tonight to try and resolve the error. The custom authorise attribute was removed from the controller and even left it on at times, I even checked the AuthoriseCore override I made to see if there was something preventing the request, however no matter what I did nothing would work.
Finally, as a last ditch effort I removed the entire controller, the views and any files associated with the controller. Added a new controller using a different name, set up a new view and the JQUERY required to run Data Tables and for some reason (unbeknownst to me why) everything started working as expected.
I hate not knowing why this issue was caused and what was causing it, however I am happy the problem has been resolved. The help and advice in the comments is appreciated.
Edit
So a few moments ago I found the cause of the issue whilst making some changes to the Route Config file. Leading back to a comment I made in the original question, it was stupidly obvious and the reason why removing the controller worked is because the original controller had 2 RouteConfigs under 2 separate names, whereas the new controller hadn't been set-up in RouteConfig at the time. Therefore, the controller was getting confused and had no idea which one to look at, meaning it threw a hissy fit and decided it didn't want to work.
In an ASP.NET MVC 4 project, I've added an MVC Controller with scaffolding from an EF class. I.e, CRUD operations. They all work. If I add action methods by hand, add an Html.ActionLink() to a view pointing to them, I get 404 errors.
For example, in my controller I add the AddImage method:
public ActionResult AddImage(int id)
{
var car = db.Cars.Find(id);
return View("AddImage",car);
}
This just returns a view to add images associated with the Car object. In the corresponding Index.cshtml, I add:
#Ajax.ActionLink("Add Image", "AddImage", new { id = item.CarId }, new AjaxOptions { UpdateTargetId = "modal",OnSuccess="showDialog" })
When it renders, in the console, I see a 404 when that link is clicked. Another weird thing is that when I run in the debugger, a breakpoint set in the method is hollow with a little warning icon, says no executable code is associated with this line.
I have added nothing to the RouteConfig: it just has the Default, which should work. I had an overload with an HttpPost attribute, but even without that, I still get a 404.
In previous projects, I can Action methods with impunity and they all work. So what is the problem here?
Please help, Stackoverflow, you're my only hope.
With the help of David in the comments, I think I figured out what I did to get my project in a weird state. To be brief: I added stuff to my model including adding a migration without calling Update-Database. I tried running the app without the database being up to date.
I wasn't getting an error that said as much, but after restarting VS, deleting the bin and obj folders for the project, changing the output path to just bin/ instead of bin/Debug (found on many Stackoverflow questions), I finally got the right error message.
Then I ran my update, et voila! Working project.
write this
public ActionResult AddImage(int id)
{
var car = db.Cars.Find(id);
return View(car);
}
and your link must be 'AddImage' without empty space
#Ajax.ActionLink("AddImage", "AddImage", new { id = item.CarId }, new AjaxOptions { UpdateTargetId = "modal",OnSuccess="showDialog" })
So I saw this question here on SO, but it hasn't really solved this problem for me.
I have an ASP.NET MVC 3 + Razor app running on IIS5 on my dev pc, and then IIS6 for my dev web server. Everything worked great until I deployed it. I am bin deploying everything, with no problems on that front (that I can tell).
Now I am getting this Child actions are not allowed to perform redirect actions error on my page. I am not sure how to pinpoint where it is failing.
I'm using #Html.Action to pull in some drop down boxes with data:
public ActionResult Hierarchy()
{
List<Store> storeList = DBService.getStores();
if (DBService.Error != null)
return RedirectToError(DBService.Error);
List<Department> deptList = DBService.getDepts();
if (DBService.Error != null)
return RedirectToError(DBService.Error);
VM_Hierarchy hierarchy = new VM_Hierarchy(storeList, deptList);
return View(hierarchy);
}
If I remove the #Html.Action line, the page will render. It will then break if I do an AJAX request to a controller action such as this:
[HttpPost]
public ActionResult InventoryList(string fromDate, string toDate)
{
List<Inventory> inventories = DBService.getInventories(fromDate, toDate);
if (DBService.Error != null)
return RedirectToAction("Error");
return View(inventories);
}
If this isn't correct, how am I supposed to redirect to an error page or dictate what view gets returned on a post? Any help is appreciated. Thanks.
It's probably because you're getting errors from your DB service when it's deployed, which you aren't getting locally. This is causing it to try and redirect from a child action, which you can't do.
You might want to try getting the drop-down data in your main action, and put it all in a ViewModel, so you aren't using child actions. If this fails, you can redirect to your heart's content. For the AJAX, you'll need to handle the errors on the client and do something sensible, you can't just return a redirection from an AJAX call.
This question has some further info:
Why are Redirect Results not allowed in Child Actions in Asp.net MVC 2
if you put in the child action
(ControllerContext.ParentActionViewContext.Controller as System.Web.Mvc.Controller).Response.Redirect(Url.Action("Action", "Controller")); it will redirect from the childaction.
I had a similar problem but for the life of me, I couldn't figure out where the redirection was coming from. Once I figured it out, I thought I'd post an answer in case it happens to anyone else.
If the source of the redirection is not apparent from the imperative code, e.g.:
[AuthoriseThis]
public ActionResult Details(SomethingModel something)
{
return PartialView(something);
}
Look at the declarative code!
In my case, it was an authorisation problem, so the attribute was causing the redirection, and my eyes were filtering out the existence of the attribute.