Json invoke not working after moving to mvc5 - javascript

Same code stopped working after move to mvc5. In the following code I am trying to get cities for a country which is chosen in a dropdownlist using json.
The View.cshtml
#Html.DropDownList("CountryId", (SelectList)ViewBag.Countries, " -- choose a country -- ", new { onchange = "CountryDDLChanged()", #class = "form-control" })
JavaScript file (a part of the code)
function CountryDDLChanged() {
var url1 = "../Country/GetCitiesByCountryId";
var countryid = $("#CountryId").val();
$.ajax({
type: "GET",
url: url1,
data: { countryId: countryid },
dataType: "json",
success: function (result) {
alert("yes");
},
error: function(req, status, error){
alert(error);
}
});
}
CountryController
public JsonResult GetCitiesByCountryId(int countryId)
{
JsonResult result = new JsonResult();
using (var db = new DBContext())
{
List<City> cities = db.Cities.Where(c => c.CountryId == countryId).ToList();
result.Data = cities;
result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
}
return result;
}
When I digg down in the code and debugging it. it generates this error.
he ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
Why this works in MVC4 but not in MVC5? is it because of different version of EF?
how can I solve it?
UPDATED: Here is my Country Entithy and City :
[Table("Country")]
public class Country
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int CountryId { get; set; }
[StringLength(100)]
public string Name { get; set; }
public virtual List<City> Cities { get; set; }
public virtual List<Member> Members { get; set; }
public virtual List<MemberFee> MemberFees { get; set; }
}
[Table("City")]
public class City
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int CityId { get; set; }
public string Name { get; set; }
public int CountryId { get; set; }
[ForeignKey("CountryId")]
public virtual Country Country { get; set; }
public virtual List<Member> Members { get; set; }
}

Related

Null value while trying to send a DropDownList value to an ajax function in a Modal using MVC - Entity

I'm creating a new MVC WebSite using EntityFramework and, on my _Layout.cshtml I'm calling a PartialView, which is a Modal to insert a record on a specific table.
The partial view contains the following DDL:
<div class="form-group">
#Html.LabelFor(model => model.Currency, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<select class="form-control" id="CurrencyId" name="CurrencyId">
<option value="">Select currency...</option>
</select>
</div>
</div>
It uses an autogenerated model:
using System;
using System.Collections.Generic;
public partial class Property
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Property()
{
this.Attachments = new HashSet<Attachment>();
this.BankAccountCorrienteProperties = new HashSet<BankAccountCorrienteProperty>();
this.Contracts = new HashSet<Contract>();
this.Photos = new HashSet<Photo>();
this.Renters = new HashSet<Renter>();
}
public int IdProperty { get; set; }
public Nullable<int> IdOwner { get; set; }
public Nullable<int> PropertyType { get; set; }
public string StreetName { get; set; }
public Nullable<decimal> SquareMetersSize { get; set; }
public Nullable<bool> Garage { get; set; }
public Nullable<int> PropertyStatus { get; set; }
public string ConstructionDate { get; set; }
public Nullable<short> RentOrSell { get; set; }
public Nullable<int> Currency { get; set; }
public Nullable<decimal> Price { get; set; }
public string Notes { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Attachment> Attachments { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<BankAccountCorrienteProperty> BankAccountCorrienteProperties { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Contract> Contracts { get; set; }
public virtual Currency Currency1 { get; set; }
public virtual Owner Owner { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Photo> Photos { get; set; }
public virtual PropertyType PropertyType1 { get; set; }
public virtual PropertyStatu PropertyStatu { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Renter> Renters { get; set; }
}
And to load the data into the dropdown I had to use Ajax as follows:
getDdlInfo("../Currency/ListCurrencies", function (result) {
$.each(result.data, function (key, item) {
$("#CurrencyId").append($('<option></option>').val(item.CurrencyId).text(item.CurrencyName));
});
function getDdlInfo(path, callBackFunct) {
$.ajax({
type: "GET",
url: path,
success: function (result) {
return callBackFunct(result);
},
error: function (data) {
}
});
For then sending the value to the controller, where an HTTP Post is there to send data to database:
function createProperty() {
$.ajax({
url: '../Property/CreateProperty',
type: 'POST',
cache: false,
async: true,
data: $('form').serialize(),
success: function (result) {
//TODO: Modal de propiedad cargada
}
});
My problem here is that:
1) Whenever createProperty() goes into the controller, all data is there, except for the dropdown. It gets to the controller always null, no matter if I select a value or not and...
2) Is this the correct approach for this? Am I missing something? I tried using Razor DropDownList but I couldn't find the way to do it correctly.
Thank you.
On your model the property is called Currency, so your input's name needs to match that to successfully model bind. Changing the name on the input to Currency should resolve it.
<select class="form-control" id="CurrencyId" name="Currency">

Some elements from JSON object passed to MVC controller are NULL

I am trying to pass a JSON object to my MVC controller action via POST. The controller action is called but some elements of the object are NULL. The 'ArticleKey' is there but the 'MeasureDefinitions' are NULL (see below).
Here is the object which I am trying to parse (it gets appended with more values by the user):
var articleValues = [
{
'ArticleKey': {
'ArticleNo': 'ArticleNo',
'CustomerName': 'CustomerName',
},
'MeasureDefinitions ': [
{
'DisplayIndex': 0,
'MeasureType': 'MeasureType',
'Percentage': 99.99,
'OriginalPercentage': 0
}
]
}
];
My model looks like this:
public class ArticleValuesModel
{
[Key]
public ArticleKey ArticleKey { get; set; }
public List<MeasureDefinition> MeasureDefinitions { get; set; }
public string ArticleDescription { get; set; }
public bool AddToList { get; set; }
}
public class ArticleKey
{
public string ArticleNo { get; set; }
public string CustomerName { get; set; }
}
public class MeasureDefinition
{
public long DisplayIndex { get; set; }
[Key]
public string MeasureType { get; set; }
public double Percentage { get; set; }
public double OriginalPercentage { get; set; }
}
Here is my controller action:
[HttpPost]
public ActionResult UpdateArticleValuesJson(List<Gui.Models.ArticleValuesModel> modelList)
{
return RedirectToAction("Index");
}
Here is my Ajax POST:
$('#btnSaveArticleValues').click(function() {
$.ajax({
url: "/ArticleList/UpdateArticleValuesJson",
contentType: "application/json;charset=utf-8",
dataType: "JSON",
type: "POST",
data: JSON.stringify(articleValues),
success: function() {
console.log("Saved");
},
error: function(e) {
console.log(e);
}
});
});
Can you please help me to make the 'MeasureDefinitions' list accessible in my controller?
Removing the extra spaces in my JSON object like indicated by the_lotus did help to resolve the problem.

When creating double dropdown SelectList with JQuery on POST returns 0. ASP.Net CORE 2.1

I have created two dropdownlists, of which one acts as a filter for the other. So, with dropdown Customer a customer is selected and only a limited set of ClientUsers is presented in in the dropdown ClientUser. I use a Jquery function to make this happen.
The selection works excellent, but when I POST the form the ClientUser is set to 0, instead of the choice.
The View is as follows (simplified for readability purposes):
#model DropDownTester2.Models.CaseViewModel
<form asp-action="Maak">
<label asp-for="CaseTitle" class="control-label"></label>
<input asp-for="CaseTitle" class="form-control" />
<select id="customerId" asp-for="CustomerId" asp-items='#(new SelectList(ViewBag.customers, "CustomerId", "CompanyName"))'>
<option>Select Customer Name</option>
</select>
<select id="clientUserId" asp-for="ClientUserId" asp-items='#(new SelectList(string.Empty, "ClientUserId", "LastName"))'>
</select>
<input type="submit" value="Maak" class="btn btn-default" />
</form>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script src="~/lib/jquery/dist/jquery.js"></script>
<script type="text/javascript">
$(function () {
$("#customerId").change(function () {
var url = '#Url.Content("~/")' + "Case/getClientUserById";
var ddlsource = "#customerId";
$.getJSON(url, { id: $(ddlsource).val() }, function (data) {
//$.getJSON("#Url.Action("getClientUserById","Case")", { id: $(ddlsource).val() }, function (data) {
var items = '';
$("#clientUserId").empty();
$.each(data, function (i, row) {
items += "<option value='" + row.value + "'>" + row.text + "</option>";
});
$("#clientUserId").html(items);
})
});
});
</script>
}
The CaseViewModel is:
public class CaseViewModel
{
public int CaseId { get; set; }
public string CaseTitle { get; set; }
public int CustomerId { get; set; }
public int ClientUserId { get; set; }
public IEnumerable<Customer> CustomerList { get; set; }
public IEnumerable<ClientUser> ClientUserList {get; set;}
My Model for Case is:
public class Case
{
public int CaseId { get; set; }
public string CaseTitle { get; set; }
public string CaseRoleDescription { get; set; }
public int CustomerId { get; set; }
public int ClientUserId { get; set; }
public virtual Customer Customer { get; set; }
public virtual ICollection<ClientUser> ClientUsers { get; set; }
}
Finally my controllers are :
// GET: Case/Maak
public IActionResult Maak()
{
ViewBag.customers = _context.Customer.ToList();
return View();
}
public JsonResult getClientUserById(int id)
{
List<ClientUser> list = new List<ClientUser>();
list = _context.ClientUser.Where(c => c.Customer.CustomerId == id).ToList();
list.Insert(0, new ClientUser { ClientUserId = 0, LastName = "Please select a clientuser" });
return Json(new SelectList(list, "ClientUserId", "LastName"));
}
// POST: Case/Maak
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Maak(CaseViewModel model)
{
if (ModelState.IsValid)
{
var newCase = new Case
{
CaseId = model.CaseId,
CaseTitle = model.CaseTitle,
CustomerId = model.CustomerId,
ClientUserId = model.ClientUserId
};
_context.Add(newCase);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["CustomerId"] = new SelectList(_context.Set<Customer>(), "CustomerId", "CustomerId", model.CustomerId);
return View(model);
}
I can't reproduce your issue :
The difference part of codes is that i create the Customer/ClientUser manually but that shouldn't be the issue cause :
public class Customer {
public int CustomerId { get; set; }
public string CompanyName { get; set; }
}
public class ClientUser
{
public int ClientUserId { get; set; }
public string LastName { get; set; }
}
You may search the "ClientUserId " in your pages to confirm whether other function reset the value .
As a workaround, you can also :
Create a hidden filed in your page and bind to your model property , create the select change event javascript function to set the value based on the selection .
Use Jquery to get the selected opinion , use Ajax to call action function and pass the value as parameter .

Post Kendo Multiselect values to controller

I seem to be having a problem posting the selected values from my Kendo Multiselect widget to an action on my controller. I've never had this issue before and as far as I know I am doing everything right, but something is obviously causing an issue.
I have this input on my view:
<input id="ProductHandlingTypes" name="ProductHandlingTypes" style="width: 100%"/>
My ViewModel
public class BuyerProfileViewModel
{
public string UserId { get; set; }
public string Name { get; set; }
public int BuyerTypeId { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zipcode { get; set; }
public string Description { get; set; }
public List<int> ProductHandlingTypes { get; set; }
public bool Producer { get; set; }
}
And my JavaScript:
$("#ProductHandlingTypes").kendoMultiSelect({
placeholder: "-- Select Type(s) --",
dataTextField: "Name",
dataValueField: "Id",
dataSource: new kendo.data.DataSource({
transport: {
read: {
url: "/Helper/GetProductHandlingTypes",
dataType: "json",
type: "GET"
}
}
})
});
$("#btnSave").on("click", function (e) {
e.preventDefault();
var formCreate = $(".form-register-buyer");
formCreate.validate();
if (formCreate.valid()) {
var options = {
url: $(formCreate).attr("action"),
type: $(formCreate).attr("method"),
data: $(formCreate).serialize()
};
$.ajax(options)
.done(function(data) {
if (data.success === true) {
window.location.href = data.redirectTo;
} else {
toastr.options = { "postiionClass": "toast-bottom-full-width" };
toastr.error(data.message, "Uh, Oh!");
}
});
}
});
When I submit my form to the controller I can see that all of the correct values are being passed except for ProductHandlingTypes. It just says it has a count of 1 and when I expand it out it says 0.

KendoUI treeview children are displayed as undefined

I have a treeview in kendoUI in which main nodes are calling into an mvc controller and that controller looks to whether there is an nullable id passed in and then uses a different model.
What I hit the url : http://localhost:2949/Report/GetReportGroupAssignments
I see this JSON
[
{"Id":1,"ReportGroupName":"Standard Reports","ReportGroupNameResID":null,"SortOrder":1},
{"Id":2,"ReportGroupName":"Custom Reports","ReportGroupNameResID":null,"SortOrder":2},
{"Id":3,"ReportGroupName":"Retail Reports","ReportGroupNameResID":null,"SortOrder":3},
{"Id":4,"ReportGroupName":"Admin Reports","ReportGroupNameResID":null,"SortOrder":5},
{"Id":5,"ReportGroupName":"QA Reports","ReportGroupNameResID":null,"SortOrder":4}
]
Now my mvc controller looks like this
public JsonResult GetReportGroupAssignments(int? id)
{
var model = new List<ReportGroup>();
var defModel = new List<ReportDefinition>();
try
{
if (id == null)
{
model = _reportService.GetReportGroups("en-us").ToList();
return Json(model, JsonRequestBehavior.AllowGet);
}
else
{
defModel = _reportService.GetReportDefinitions().Where(e=>e.ReportGroupID ==Convert.ToInt32(id)).ToList();
return Json(defModel, JsonRequestBehavior.AllowGet);
}
}
catch (Exception ex)
{
Logger.Error(ex, "Error loading LoadReportList.");
return null;
}
}
My Kendo javascript looks like the following:
var serviceRoot = "/Report"; // "//demos.telerik.com/kendo-ui/service";
homogeneous = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: serviceRoot + "/GetReportGroupAssignments", //"/LoadReportTree", // "/Employees",
dataType: "json"
}
},
schema: {
model: {
id: "Id" //"ReportGroupName"
,hasChildren: "Id"
}
}
});
var treeview = $("#treeview").kendoTreeView({
expanded: true,
dragAndDrop: true,
dataSource: homogeneous,
dataTextField: "ReportGroupName"
}).data("kendoTreeView");
Seems that the calls (which I discovered that children records have a "load" method that it called behind the seens, so basically I pass in the ID in order to get the data from the other model ( table in db)
(Id is mapped with automapper to ReportGroupID )
So when i click to the left of "Standard Rports" I am getting all of these children as undefined, How do I get these to show up properly?
Update: My ReportDefinition class:
public class ReportDefinition {
public override int Id { get; set; }
public string ReportKey { get; set; }
public string ReportName { get; set; }
public int? ReportNameResID { get; set; }
public string ReportDef { get; set; }
public int? ReportDefinitionResID { get; set; }
public string ReportAssembly { get; set; }
public string ReportClass { get; set; }
public int ReportGroupID { get; set; }
public int AppID { get; set; }
public int SortOrder { get; set; }
public bool IsSubReport { get; set; }
}
I think your problem is that the class ReportDefinition does not have a property called: ReportGroupName. That is why TreeView displays 'undefined'.
Try adding this Property to your ReportDefinition class like:
public class ReportDefinition {
// Other Properties
// I guess this property is missing
public string ReportGroupName { get; set; }
}

Categories

Resources