Data Binding in DevExtreme Drop Down Box not working - c#

Anyone using DevExtreme to create ASP.NET MVC project here? I just want to create a simple drop down box that bind data source come from the controller. Here is how it works inside the controller, I create a list of object, then I add the model having two fields "Key" and "Value" into the list. So I pass the list of object in return view in the controller.
As you can see from the screenshot above while I debugging the View, the Model is the list of object that I passed in, it has data for sure. You can see there are two fields "Key" and "Value" from each item, and I also specified the ValueExpr and DisplayExpr. When I run the project, this is the result I get. I just don't know why it is still blank while my data does exist. Am I missing some code?

Without a little more detail it is tough to know for sure, but when I have run into this issue, I fixed it by checking:
If the model was in the wrong format (Not a list/IEnumerable)
The model class fields were set to private
I would also look at this link/demo DevExtreme has for SelectBox: https://js.devexpress.com/Demos/Widgetsgallery/Demo/SelectBox/Overview/Mvc/Light/
OR
DropdownBox:
https://js.devexpress.com/Demos/WidgetsGallery/Demo/DropDownBox/SingleSelection/Mvc/Light/
Otherwise, this is what I use to fill my chosen editor (I am using Dapper for SQL call):
View
#(Html.DevExtreme().SelectBox()
.ID("DemoSelectBox")
.DataSource(d => d.Mvc()
.LoadAction("GetDemoData"))
.DisplayExpr("DemoName")
.ValueExpr("DemoValue"))
Controller
[HttpGet]
public ActionResult GetDemoData(DataSourceLoadOptions loadOptions)
{
List<DemoData> demoDataGrid= new List<DemoData>();
using (SqlConnection connection = new SqlConnection(_connectionString))
{
demoDataGrid= connection.Query<DemoData>(
sql: #"SELECT DemoValue
,DemoName
FROM DemoDatabaseTable"
).ToList();
}
return Content(JsonConvert.SerializeObject(DataSourceLoader.Load(demoDataGrid, loadOptions)), "application/json");
}
Model Class
public class DemoData
{
public string DemoValue{ get; set; }
public string DemoName{ get; set; }
}

Related

How to pass two filled class models via an Angular http.post 'body' to the controller?

I am receiving an error message, "Sequence contains no elements" while trying to update a table in SQL from Angular 7 to an AspNet Core controller by passing two model parameters using an "http.post".
I am passing the data from the form to the class models with no problem because I can see the payload data in the browser console. However, when trying to pass the models as parameters in my api service to the controller, all of the parameters in the model are null. I usually don't have an issue when passing one model parm thru, but passing two of them to get to my controller with a [FromBody] doesn't seem to want to work for me.
I tried to wrap the models in curly brackets to pass them, to no avail:
UpdateService(serviceAddress: ServiceAddressModel, contact: ContactModel) {
let reqHeader = new HttpHeaders();
let body = { svc: serviceAddress, cnt: contact };
reqHeader.append('Content-Type', 'application/json');
return this.http.post(this.baseurl + 'api/customermanagement/update-service-address-info', body, { headers: reqHeader });
When I view the request / response in the browser console, I can see the data within the payload, so I know that the data is ready to pass.
My controller is set up as follows:
[Route("update-service-address-info")]
public bool UpdateServiceAddressAccount([FromBody] ServiceAddressEntity svc_id, [FromBody] ContactEntity cnt_id)
{
return serviceAddressService.UpdateServiceAddressAccount(svc_id, cnt_id);
}
Using breakpoints in this call shows null for all values.
If I can properly pass the parameters to my interface, I should be good-to-go. I am sensing that I am not structuring the parameters properly in the http.post body.
Your request body, { svc: serviceAddress, cnt: contact } is received as a json string, e.g. {"svc":{"serviceAddressProperty1":"value",...},"cnt":{"contactProperty1":"value",...}}. The parameters to your action method are bound via the default model binding mechanism (unless you provide your own custom model binding implementation). The default mechanism attempts to create instances by binding from the top level of the json object received with the request. enter code here
In simpler terms, lets assume you class ServiceAddressModel is defined like this:
public class ServiceAddressModel
{
public string Name { get; set; }
public string Property2 { get; set; }
}
the model binder looks for properties with the names "name" and "property2" at the top level of the json tree. If found, these are bound to the Name and Property2 properties of the created instance.
In your case, wrapping your models in a class that can make svc_id and cnt_id the top level properties would work fine. Like this example:
public class MyRequest
{
public ServiceAddressModel svc_id { get; set; }
public ContactEntity cnt_id { get; set; }
}
Then you can declare your action like
[Route("update-service-address-info")]
public bool UpdateServiceAddressAccount([FromBody] MyRequest request)
{
return serviceAddressService.UpdateServiceAddressAccount(request.svc_id, request.cnt_id);
}
Snake casing, camel casing should be allowed by default (you will have to try it, I havent tested that part). That is, if you declare your properties as SvcId and CntId (if you prefer more natural C# naming conventions) it should be able to bind correctly from JSONs with "svc_id" or "cnt_id".
Another option would be to implement custom model binders, but that might be a longer and more complex route.
Hope this helps.
Just try to pass the value like this and see
let body = { svc_id: serviceAddress, cnt_id: contact };

c# filter database results using EF similar to SQL WHERE Clause

I've connected to my database using Entity Framework and am building my first MVC app for use in a web page.
I can get the controller to populate public strings in my models with no problem... the issue I'm having is that I can't figure out how to filter responses from my database.
I expect to have only one item returned which I will display in the view with #Model.BusinessUnit
Here's my Model Class for the database table:
public partial class TBL_Wholesale_UWS_BusinessUnits
{
public int PrimaryID { get; set; }
public string BusinessUnit { get; set; }
public string Status { get; set; }
}
Here's what I have in my controller:
public ActionResult test(int PrimaryID)
{
var testing = new TBL_Wholesale_UWS_BusinessUnits();
// maybe putting new is the wrong thing to do as that would be wiping the class? IDK
return View(testing);
}
As you can see, the PrimaryID is passed to the controller via the querystring and this is recognised without issue, but I'm at a loss as to where to add the filter, I assumed it would be something like...
var testing = TBL_Wholesale_UWS_BusinessUnits.Where(TBL_Wholesale_UWS_BusinessUnits.PrimaryID = PrimaryID);`
but Visual Studio is telling me in no uncertain terms that this this wrong.
Had this been classic asp I would have just made a record set and used the where clause in SQL, but as this is built with the Entity Framework to do my connecting I don't really know where to start.
Any help would be greatly appreciated.
If you are only trying to return that one specific object to the view.. then you need to find that int PrimaryID in the database and retrieve that specific record.
What you are doing is simply creating a new instance of the TBL_Wholesale_UWS_BusinessUnits class which is empty.
Try this:
public ActionResult test(int PrimaryID)
{
var testing = db.TableName.Find(PrimaryID);
// db = Whatever the variable holding your connection string is.. maybe DbContext
// TableName = Whatever table in your database that holds the record you want
// This will return the specific object that you are looking for
return View(testing);
}
I hope this helps!

Where is the DbContext extension method storing data?

I'm working with creating a partial view to allow the end user to add an item for a later submission.
I have the following class defined as a ViewModel:
public class AddItemsContext : DbContext
{
public DbSet<Item> Items { get; set; }
}
Connection string:
I then have an AJAX call that uses this function to add an item to my partialview:
[HttpPost]
public ActionResult Index_AddItem(SearchedItem viewModel, string Text, string Value)
{
AddItemsContext db = new AddItemsContext();
string test = Request.Form.GetValues("cbxPerm")[0].ToString(); // to be used later
Item NewItem = new Item();
NewItem.ItemName = "test"; // just set it to a temp var for testing
db.Items.Add(NewItem);
db.SaveChanges();
return PartialView("_AddItems", db.Items);
}
The item list does build in my partial view but then I noticed the list persists even after stopping and restarting my app. I thought it may be writing in the SQL DB but I don't see it there either.
I found this: where is data stored? but I don't have any other datasource defined other than my main app's DB.
I also read this: DbContext disposing? which appears to be saying that the data should be disposed on exit.
This partial view needs to add/remove items before the form is submitted for a DB write.
I'm trying to understand why/where the data is being stored permanently?

Asp.net MVC Composite class custom model binding

I've searched all over the web but not finding the solution for the following problem:
Say I have three ViewModel classes
public class ViewModelNewPerson
{
public string PersonName;
public string Address;
public string EyeColor;
//etc
}
public class ViewModelSelectPerson
{
public int SelectedPersonId;
}
public class ViewModelComposite
{
public ViewModelSelectPerson selectViewModel;
public ViewModelNewPerson newPersonViewModel;
}
and I want to do the following things:
In the Controller I want to create a GET Action which uses the class ViewModelComposite as its Get model, and in the view I want the user choose from the following two available actions: to choose a existed person, and to add a new person as the selected value.
So I need to create two forms in the View, and there would be two POST Actions added to the Controller using the Post model of class ViewModelNewPerson and ViewModelSelectPerson.
My question is, how can I do the manual model binding using a Custom Model Binder that can convert the Composite class of ViewModelComposite to ViewModelNewPerson in the Action of create a new person, and to ViewModelSelectPerson in the Action of select an existing person?
EDIT:
Now I have an idea of decomposing the class ViewModelComposite and declare every property in the two classes into the composite class, and the default model binder will do the trick, I think. But that'll drop the composite pattern, and is not something I wanted.
You would use one single view model in your form, you would have a post action that receives your single view model.
In your Controller code:
public ActionResult GetSomeData(MyCustomViewModel model){
// add the first element
var person = Person.Add(model.Person);
// update the second object in model, with related / needed ID
model.PersonContent.PersonId = person.id;
// add in related content
var AddedContent = PersonContent.Add(model.PersonContent);
}
single form, multiple actions, multiple tables

Passing and returing data to a simple grid form using ASP.NET MVC

I have page with a simple table and advanced search form. I pass List<Customers> to the model:
View(List<Customers>);
So what is best way to pass and return data to the search form? I want to use validation or something but I think passing data through ViewData is not good idea. Any suggestions?
You should wrap all your data that is required by you view in a model specific to that view. The advantage to this is you could also include your search criteria in the model which would be empty at first but when your search posted, the model would automatically contain your search criteria so you could reload it when passing back the results. This will help maintain your state between post's as well.
This also allows all your view's data to be type safe where ViewData would not be.
Eg:
public class CustomerSearchViewModel
{
public List<Customer> Customers { get; set; }
// your search criteria if you want to include it
public string SearchFirstName { get; set; }
public string SearchLastName { get; set; }
public int SearchCustomerID { get; set; }
// etc...
}
When you return back the List<Customer> the search criteria would already be filled in your model from the post so your view can default the search criteria back to the corresponding controls (assuming your search results and search inputs controls are on the same view).
For example, in your post you would accept a CustomerSearchViewModel. Then all you need to do is get your list of customers and add it back to the model and return the same model.
// assuming you have accepted a CustomerSearchViewModel named model
model.Customers = GetCustomersForSearchCriteria(model.SearchFirstName,
model.SearchLastName, model.SearchCustomerID);
return View(model);
You could also add the validation attributes to your model properties to leverage the built in validation in MVC. This would not be possible if you were using ViewData to pass this data around.
You have to also consider the 'next guy'. It's cleaner when all the data that the view requires is located in a single class. This way they don't have to hunt through the code to discover if ViewData is being used and what data is actually being passed around in it.
ViewData is still an option for passing data but I try to minimize the use of it if at all possible.
Rather than passing just a list of items to your View, create a class which contains your list of items and any other data you might need, i.e. a ViewModel.
public class CustomerSearchViewModel {
public IEnumerable<Customer> Customers { get; set; }
public string SearchTerm { get; set; }
}
.....
var viewModel = new CustomerSearchViewModel {
Customers = customerList,
SearchTerm = searchTerm
};
return View(viewModel);

Categories