i have class bound to repeater as a list here is structure of class
public String Name { get; set; }
public String Description { get; set; }
public List<ProductRecord> ProductList { get; set; }
i can get Eval("Name") on aspx page. How do i go about accessing ProductList properties in Eval e.g ProductRecord has Name property
Thank you in advance
You need to tell the Eval which one of the multiple ProductRecord you want. The problem is that you want to navigate a 1 to many relationship and get a value from the many. You have to make it a 1 to 1 relationship. For this you could either specify a single element like:
Eval("ProductList[0].Name")
Another option would be to put ProductList on a new Repeater, so you can show all the ProductList's properties for your structure. Or concatenating all values into a single value for display.
Related
I'm learning asp.net mvc and wonder when we need to use BindAttribute.
The first case (using Bind):
Model:
public class Book
{
public string Id { get; set; }
public string Name { get; set; }
public string Author { get; set; }
}
Controller:
public IActionResult Create([Bind(nameof(Book.Name), nameof(Book.Author))] Book model)
{
return Ok();
}
The book Id would be generated on server side. So, client side has nothing to do with it, every actions try to change/make the id is prevented.
The second case (not using Bind):
Model:
public class BookViewModel
{
public string Name { get; set; }
public string Author { get; set; }
}
Controller:
public IActionResult Create(BookViewModel model)
{
return Ok();
}
Because the second model doesn't contain Id property, we don't need to prevent from creating or changing.
I prefer the second. It's easy to manage model.
Is there a case we must use Bind attribute?
We use bind when we want that some properties of complex property are ignored when received on server. It could be for safety or other reasons.
When this action is executed the MVC model binder will use the request parameters to populate the user parameter's properties, as you may already know. However, the Bind attribute tells the model binder to only populate properties with names specified.
So in this case only the Username, FullName and Email properties will be populated. All others will be ignored.
See here for more details: http://ittecture.wordpress.com/2009/05/01/tip-of-the-day-199-asp-net-mvc-defining-model-binding-explicitly/
If you have situation when you only have to ignore one parametar from binding you could use Exclude property:
[Exclude]
public Entity Name {get; set;}
Bind is used to increase security and unauthorized data to be posted on server . In your model class , suppose you have content property also. if the content property is not needed in the future. Then it would be difficult for you to remove all the occurrences of that property. Here you can use bind property like this
[Bind(exclude="content")]
or you can bind only selected properties to be posted on server by including the properties like this
public ActionResult create([Bind(Include = "Name,Author")] Modelclass modelclass)
{
//Do something here
}
You can learn more about it here
Second approach is more suitable instead writing all the properties and bind them but there are some situations where you must bind user like you have a roles property or IsAdmin property in your model then you might not want that user somehow posts the IsAdmin or roles properties to the server . That's where you can use Bind attribute
I have two classes:
public class Contact{
public string contact { get; set; }
public string contact_type { get; set; }
}
public class Person{
public string first_name { get; set; }
public string last_name { get; set; }
Contact phone
}
In my asp.net application I need to see list of persons in a gridview.
I use ObjectDataSource to bind List. But only two columns: first_name and last_name are presents in the gridview. It is important to see contact of person.
In other words, how to bind subclass Contact to the same gridview.
What is the best way to do this? I don't like idea to use DataTable.
Thanks!
I think your best bet is to use template field and eval to access inner object fields:
<asp:TemplateField HeaderText="Contact">
<ItemTemplate>
<%# Eval("phone.contact") %>
</ItemTemplate>
</asp:TemplateField>
If you are using auto generated columns feature, keep it, declared columns will be appended after generated ones.
I'm using a class to generate an SQLite table, but I also want to use it as ItemSource for a two levels ListView (A listview with sub items).
This works for the ListView:
public class ParentModel:List<ChildrenModel>
{
[PrimaryKey]
public string uid { get; set; }
public string name { get; set; }
[Ignore]
public string attributeA { get; set; }
public ParentModel() {
}
}
But when I do mySQLiteConnection.CreateTable<ParentModel>(); it throws an Exception because the Object is a List<>.
I can [Ignore] attributes, but is there a way to ignore the fact that the the class is a List<>?
I can also create a List variable inside the model and [Ignore] it, but this wouldn't work for the ListView.
The only solution I can think is creating two classes with the same attributes, one being a List<> and the other one not.
But I really don't like this idea.
Not sure why you want to inherit from List<ChildrenModel>. You should make the ChildrenModel class a class that can create a table, and then that table would have all of the ChildrenModel items. Then in ParentModel you could have a public property of type List<ChildrenModel> which you can load from the ChildrenModel table. You would want to ignore that property as SQLite can not store a List. You can then access your populated List through the public property for the List<ChildrenModel> in the ParentModel class. That's what I would do anyway.
I'm working with ASP.NET MVC 4, but I on't think that matters for the purpose of this question.
I have a relatively complex model for my edit view. Like this:
public class Recipe_model
{
public string Name { get; set; }
public List<Recipe_Ingredient_model> Ingredients { get; set; }
}
where Ingredients is
public class Recipe_Ingredient_model
{
public int RecipeID { get; set; }
public int? UnitID { get; set; }
public double? Quantity { get; set; }
public Ingredient_model Ingredient { get; set; }
}
which itself contains the Ingredient model.
When I make a form for this, the built-in Html.EditorFor() doesn't work for anything past the properties of the Recipe_model, so I'm using partial views to display the editor for each of the sub-models.
That works fine as far the interface goes, but when I submit the form to the controller and try to bind to the Recipe_model automatically using
[HttpPost]
public ActionResult Edit(Recipe_model model)
{
return View(model);
}
it fails because the ids of the input elements in the partial views do not conform to the correct pattern (I think ParentModel_Property).
Short from hard-coding the ids in the partial view or binding manually from the FormCollection in the controller, is there some way to get the correct ids generated in the partial view so that the model will bind automatically on submit?
This is common problem. Instead of simple partials, use EditorTemplates (special folder for models) and binding will work automatically.
For example look at this question: Updating multiple items within same view
in addition to the answer given by #WebDeveloper
you can also try and create a custom model binder though a little more complex but will add to the ease of posting and binding form value to the objects in long run
have a look here http://patrickdesjardins.com/blog/asp-net-mvc-model-binding
you will have to manually take all the form values and bind them to the model once and then you will be able to use the #HtmlFrom methods on the razor to do anything and you will get all the value inside the objects inside the action methods as you like.
I have something like this in my code and I am getting error: Exception Details: System.ArgumentException: Value cannot be null or empty.
Parameter name: name . What am I doing wrong ? Thanks for help
#model IEnumerable<NHibernateFluentProject.Patient>
#Html.ListBoxFor(model => model, new SelectList(Model,"ID", "FirstName"));
#Html.ListBoxFor is used for your strong typed viewmodel. which could help to bind to your property. First part will take a lambda expression for a single item as a default seleced for your listbox, second part will take the item collections to dispaly all the listbox items.
For example: you have following two classes.
public class HospitalViewModel
{
public string SelectedPatient { get; set; }
public IEnumerable<Patient> AllPatients { get; set; }
}
public class Patient
{
public int Id { get; set; }
public string FirstName { get; set; }
}
From you view, you should do something like
#model HospitalViewModel
#Html.ListBoxFor(model => model.SelectedPatient, new SelectList(Model.AllPatients,"Id", "FirstName"));
OR if you only want to bind all your patients to a listbox, then use Html.ListBox instead
#model IEnumerable<Patient>
#Html.ListBox("ListBoxName", new SelectList(Model,"Id", "FirstName"));
You need to pass a lambda expression containing the property to bind the listbox to.