trying to create a cascading dropdownmenu with jsonresult and ajax, but i cant see why am i getting 500 Internal Server Error. The error occurs above the following method :
[HttpGet]
public JsonResult GetModels(string brandID="")
{
List<Model> models = new List<Model>();
int ID = 0;
if (int.TryParse(brandID, out ID))
{
using (CarsEntities1 dc = new CarsEntities1())
{
models = dc.Models.Where(a => a.Brand_ID == ID).OrderBy(a =>a.Model_name).ToList();
}
}
if (Request.IsAjaxRequest())
{
return new JsonResult
{
Data = models,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
return new JsonResult
{
Data = "Not valid request",
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
I use the method to pass a list of items into DropDownMenu and try to output the list by the following code :
$(document).ready(function () {
//if (typeof ($) == 'function') alert('jQuery is loaded.');
$("#brand_Brand_ID").change(function () {
// this will call when Brand Dropdown select change
var brandID = parseInt($("#brand_Brand_ID").val());
if (!isNaN(brandID)) {
var ddModel = $("#Model_ID");
ddModel.empty(); // this line is for clear all items from Model dropdown
ddModel.append($("<option></option").val("").html("Select model"));
// Here I will call Controller Action via Jquery to load Model for selected Brand
$.ajax({
url: "#Url.Action("GetModels","ModelSpec")",
type: "GET",
data: { brandID: brandID },
dataType: "json",
success: function (data) {
if (data != null && data.success) {
$.each(data, function (i, val) {
ddModel.append(
$("<option></option>").val(val.Model_ID).html(val.Model_name)
);
});
}
},
error: function () {
alert("Fail");
}
});
}
});
});
All i get is the following :
GET http://localhost:2508/ModelSpec/GetModels?brandID=2 500 Internal Server Error jquery-1.7.1.js (line 8102)
Also i noticed the error doesnt occur when theres no data passing through the GetModels method. And sometimes i get :
GET /ModelSpec/GetModels?brandID=5 401 Unauthorized
As soon as GetModels returns anything the error occurs else not.
The ObjectContext instance has been disposed and can no longer be used for
operations that require a connection
Stacktrace :
http://pastebin.com/3aXg7YiM
You need to move your return statements inside the using block
The Db context is disposed before you return statement is executed
public JsonResult GetModels(int brandID)
{
List<Model> models = new List<Model>();
using (CarsEntities1 dc = new CarsEntities1())
{
models = dc.Models.Where(a => a.Brand_ID == brandID).OrderBy(a =>a.Model_name);
if (Request.IsAjaxRequest())
{
return new JsonResult
{
Data = models.ToList(),
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
return new JsonResult
{
Data = "Not valid request",
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
json return type has to be primitive, so i changed the code accordingly(swap List to String[] and OrderBy to Select:
public JsonResult GetModels(int brandID)
{
String[] models;
using (CarsEntities1 dc = new CarsEntities1())
{
models = dc.Models.Where(a => a.Brand_ID == brandID).Select(a=> a.Model_name).toArray();
if (Request.IsAjaxRequest())
{
return new JsonResult
{
Data = models,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
return new JsonResult
{
Data = "Not valid request",
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
Related
This script is supposed to send a ProductId to the home controller's Delete-method, and the controller should make the appropriate Remove-operation:
$('[name="DeleteItem"]').click(function (e) {
$.ajax({
type: "DELETE",
url: "#Url.Action('Delete','Home')",
data: { id: $('DeleteItem#data-id').val() },
success: function () {
alert("success!");
window.location.replace("#Url.Action('Index', 'Home')");
},
error: function (data) {
alert("Error: " + data.id);
}
});
});
This is the form:
<form asp-action="Update">
#foreach (var item in Model.ShoppingCartItems)
{
#item.ProductTitle
<input asp-for="#item.Quantity" />
<button name="DeleteItem" data-id="#item.ProductId">DELETE</button>
}
<button type="submit">Update quantity</button>
</form>
This is the controller's Delete-method (I don't have the ShoppingCartId, so I'm getting it based on SessionId, which is stored in the ShoppingCarts-table):
[HttpDelete]
//[ValidateAntiForgeryToken] // <-- Do I need this in this case?
public async Task<IActionResult> Delete(
[Bind("ShoppingCartItemProductId")]
ViewModelAddToCart model)
{
// Initialize session to enable SessionId
HttpContext.Session.SetString("_Name", "MyStore");
string SessionId = HttpContext.Session.Id;
var ShoppingCart = new ShoppingCart()
{
SessionId = SessionId
};
var ShoppingCartItem = new ShoppingCartItem()
{
ProductId = model.ShoppingCartItemProductId,
};
if (ModelState.IsValid)
{
// Find ShoppingCart containing current SessionId.
var cartInfo =
(from Cart in _context.ShoppingCarts
where Cart.SessionId == SessionId
select new { TempId = Cart.Id })
.SingleOrDefault();
if (cartInfo != null)
{
ShoppingCartItem.ShoppingCartId = cartInfo.TempId;
}
// Find ShoppingCartItem containing current ProductId:
var cartItemInfo =
(from CartItem in _context.ShoppingCartItems
where (CartItem.ShoppingCartId == ShoppingCartItem.ShoppingCartId &&
CartItem.ProductId == model.ShoppingCartItemProductId)
select new { TempId = CartItem.Id })
.FirstOrDefault();
if (cartItemInfo != null)
{
// Delete ShoppingCartItem
ShoppingCartItem.Id = cartItemInfo.TempId;
_context.ShoppingCartItems.Remove(ShoppingCartItem);
}
await _context.SaveChangesAsync();
return RedirectToAction("Index", "Home");
}
else
{
return View("Index", "Home");
}
}
Edit I have made some changes to my code, and now I receive "Error: undefined" in an alert. That is because the error: in the ajax is triggered, and the data-object is not defined. Why is that? And a second question is what is the controller supposed to return? As I understand, not a RedirectToAction.
what is "deleteitem"
you should have some id or class for the button in your case class should be easy
<button name="DeleteItem" class = "deleteitemevent" data-id="#item.ProductId">DELETE</button>
$(".deleteitemevent").click(function (e) {
}
[HttpPost]
[ValidateAntiForgeryToken]
//^^yes you should for any post... but since you insist on
//doing ajax calls...
//you will have to research how to build this up... from JS and inject with the ajax call..
public async Task<IActionResult> Delete(
[Bind("ShoppingCartItemProductId")]
ViewModelAddToCart model)
{
//...
}
$('[name="DeleteItem"]').click(function (e) {
var dataid = $(this).attr('data-id'); // because name was used for control not id
$.ajax({
type: "POST",
url: "#Url.Action('Delete','Home')",
data: { id: dataid },
success: function () {
alert("success!");
window.location.replace("#Url.Action('Index', 'Home')");
},
error: function (data) {
alert("Error: " + data.id);
}
});
});
I think you have a long way to go... There are easier ways of doing this without needing ajax calls...
I am making a live search, where a user types something inside a text box and then via ajax results are fetched and added to a ul and in this specific case I am looking for usernames, so if a username is johnny and the user types in jo then johnny should come up and so on.
I have the ajax js code, a post method and a list model view of users, I am now trying to return the list but doesn't seem to be working.
my js:
$("input#searchtext").keyup(function (e) {
var searchVal = $("input#searchtext").val();
var url = "/profile/LiveSearch";
$.post(url, { searchVal: searchVal }, function (data) {
console.log(data);
});
});
LiveSearch view model
public class LiveSearchUserVM
{
public LiveSearchUserVM()
{
}
public LiveSearchUserVM(UserDTO row)
{
FirstName = row.FirstName;
LastName = row.LastName;
}
public string FirstName { get; set; }
public string LastName { get; set; }
}
the post method
[HttpPost]
public List<string[]> LiveSearch(string searchVal)
{
// Init db
Db db = new Db();
List<LiveSearchUserVM> usernames = db.Users.Where(x => x.Username.Contains(searchVal)).Select(x => new LiveSearchUserVM(x)).ToList();
return usernames;
}
So basically I want to return a list (or something else) of columns that contain a specific string, and pass all the results to javascript thru ajax callback.
To return the result as JSON alter your method to the following:
[HttpPost]
public JsonResult LiveSearch(string searchVal)
{
// Init db
Db db = new Db();
List<LiveSearchUserVM> usernames = db.Users.Where(x => x.Username.Contains(searchVal)).Select(x => new LiveSearchUserVM(x)).ToList();
return Json(usernames);
}
you can use like this . The idea is to use success funtion
$.ajax({
url : ""/profile/LiveSearch"",
type: "POST",
data : searchVal ,
success: function(data)
{
//data - response from server
},
error: function ()
{
}
});
and return JsonResult from Post method
I use $http request to call MVC controller and return data in JSON format. But i not able to get the result in javascript/angualr js. It return entire HTML page. Where i made the mistake?
myapp.controller('MyCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.toggle = function () {
$http({
url: "/Admin/FilterMember",
method: "GET",
params: { id: $('#txtsearch').val() }
}).then(function (result) {
alert(result);
});
};
}]);
Above is angular script in JS file.
public ActionResult FilterMember(string id)
{
SqlParameter[] SqlParam = { new SqlParameter("#Filter", id) };
DataTable dTable = MasterMindDB.dTableSP(DbConn, "SP_Get_MemberList", SqlParam);
List<Member> member = new List<Member>();
foreach (DataRow row in dTable.Rows)
{
member.Add(new Member
{
MemberName = row["Member ID"].ToString(),
Email = row["Email"].ToString(),
JoinDate = row["Join Date"].ToString(),
Status = row["Status"].ToString()
});
}
return View("Member", Json(member, JsonRequestBehavior.AllowGet));
}
Above is MVC controller
This action is for the FilerMember view
[HttpGet]
public ActionResult FilterMember () {
return View();
}
This action will be called from the client side view. No need to return a ViewResult, just the data
[HttpGet]
public ActionResult GetMemberById(string id) {
SqlParameter[] SqlParam = { new SqlParameter("#Filter", id) };
DataTable dTable = MasterMindDB.dTableSP(DbConn, "SP_Get_MemberList", SqlParam);
List<Member> member = new List<Member>();
foreach (DataRow row in dTable.Rows) {
member.Add(new Member {
MemberName = row["Member ID"].ToString(),
Email = row["Email"].ToString(),
JoinDate = row["Join Date"].ToString(),
Status = row["Status"].ToString()
});
}
//Just return JsonResult.
return Json(member, JsonRequestBehavior.AllowGet);
}
Updated client
myapp.controller('MyCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.toggle = function () {
$http({
url: "/Admin/GetMemberById",
method: "GET",
params: { id: $('#txtsearch').val() }
}).then(function (result) {
alert(result);
});
};
}]);
I have the following JQuery method for posting data to a action in my MVC contorller:
$('#btnAddNewTest').on("click", function () {
var date = $('#HIVTestTestDate').val();
var result = $('#HIVTestTestResult').val();
var cd4 = $('#HIVTestCD4Count').val();
var pID = $('#PatientID').val();
var dataToSend = { patientID: pID, testDate: date, resultID: result, cd4Count: cd4 };
$.post("/HIVInformation/AddHIVTest/", dataToSend, function (receivedData) {
location.reload(false); //Don't want to do this
});
return false;
});
Here is the Action method in my controller:
[HttpPost]
public ActionResult AddHIVTest(Guid patientID, DateTime testDate, Guid resultID, int cd4Count)
{
MvcPatientDetailsHIVViewModel model = new MvcPatientDetailsHIVViewModel(patientID);
model.LoadAllData();
try
{
//add the HIV Test
model.HIVTestResult = new Common.Models.PatientHIVTestModel()
{
ID = Guid.NewGuid(),
PatientID = patientID,
TestDate = testDate,
HIVTestResultID = resultID,
CD4Count = cd4Count
};
//call the add method
model.AddHIVTestResults();
}
catch (Exception ex)
{
ModelState.AddModelError("", ex);
}
return View("Details", model);
}
If I comment out the 'location.reload(false);' my page does not get refreshed. How do I serialize my Mvc view to be returned in the function (receivedData) delegate of the post? How do I display my view then from within the JQuery code?
if i may, i would suggest to you to use ajax, partial views, and a container div for example to load the result in it.
Example:
Script:
$(document).ready(function () {
$("#btnAddNewTest").on("click", function () {
$.ajax({
url: '#Url.Action("YourAction", "YourController")',
type: 'post',
data: {
yourData1: value1,
yourData2: value2,
},
success: function (result) {
$('#dynamicContent').html(result);
}
});
});
});
Controller:
public ActionResult YourAction(int yourData1= 1, int yourData2 = 0)
{
return PartialView("~/yourviewPath/_YourPartialView.cshtml", yourResultModel)
}
Html:
<div id="dynamicContent" class="Float_Clear">
#Html.Partial("~/yourviewPath/_YourPartialView.cshtml", Model)
</div>
Live example that I created using the same concept here
I choose from dropdown menu an item and click add => ajax call a method which return JsonResult this is all ok. Then this data should be send to another function PartialViewResult on server side: public PartialViewResult _SkupinaRow(skupinaRow skupinaRow), which generate a new tr with some textbox and labels. My problem is that no binding is made. I get Null when debuggin in _SkupinaRow(skupinaRow skupinaRow)
I have the following domain model defined:
public class skupinaRow
{
public BONUSMALUS bonusmalus { get; set; } //items
public KOLEDAR koledar { get; set; } //calendar
}
Partial View:
#model ObracunPlac.ViewModel.skupinaRow
#Html.HiddenFor(x => x.bonusmalus.bon_id)
.....
Partial view code:
public PartialViewResult _SkupinaRow(skupinaRow skupinaRow)
{
return PartialView("_SkupinaRow", skupinaRow);
}
Ajax Call:
$("#addItemPrihodki").live("click", function () {
var id = $("#prihodkidodaj option:selected").val()
var skupinaRow = {
bonusmalus:{},
koledar:{}
}
jQuery.getJSON("/Placa/getBonusMalus/?id=" + id, function (data) {
console.log("JSON Data: " + data.koledar.kol_id);
skupinaRow.koledar.kol_id = data.koledar.kol_id, //ok
skupinaRow.bonusmalus.bon_id = data.bonusmalus.bon_id, //ok
//alert(JSON.stringify(GetBonusMalusModel($("#bonusdodaj option:selected").val())));
alert(JSON.stringify(data));
// alert(skupinaRow.serialize());
$.ajax({
url: "../_skupinaRow",
cache: false,
data: JSON.stringify(skupinaRow),
//data: JSON.stringify(data),
datatype: JSON,
success: function (html) {
$("#editorRowPrihodki table tr#dodajNov").before(html);
}
,
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('error'+"+++"+textStatus+"--- "+errorThrown);
},
});
});
return false;
});
public JsonResult getBonusMalus(int id)
{
KOLEDAR koledar = db.KOLEDAR.Single(r => r.kol_id == KoledarID);
BONUSMALUS bm = db.BONUSMALUS.Single(r => r.bon_id == id);
skupinaRow model = new skupinaRow
{
koledar =koledar,
bonusmalus = bm
};
// return Json result using LINQ to SQL
return new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = model
};
}
Debug picture: https://www.dropbox.com/s/189q080irp0ny77/1.jpg
This worked when i had one model bonusmalus but now I ned two so I created modelView.
How can I bind ViewModel-SkupinaRow to Partial View with strong type SkupinaRow ?
If you are using AJAX only to convert he value to json? then you can use this approach
Set the form with normal post back to Action in controller
use jQuery in your view and on submit of form write this.
$("form").submit(function(){
$("#DropDown_Items").val(JSON.stringify(data));
});
Now you can use this in your Action Method.