0

I have two entities which are generated from data first approach of entity framework in MVC5. Following are the Models

public partial class Cuisine
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Dish> Dishes { get; set; }
}


public partial class Dish
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int CuisineId { get; set; }

    public virtual Cuisine Cuisine { get; set; }
}

When I display the Dishes it is showing as below

enter image description here

But I want the column names as Name and Cuisine Name instead of Name and Name. How to do that? I want to display as Name when showing Cuisine list and Cuisine Name when showing in Dish list.

Code for my cshtml

<table class="table">
<tr>
<th>
    @Html.DisplayNameFor(model => model.Name)
</th>
<th>
    @Html.DisplayNameFor(model => model.Cuisine.Name)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
    @Html.DisplayFor(modelItem => item.Name)
</td>
<td>
    @Html.DisplayFor(modelItem => item.Cuisine.Name)
</td>
<td>
    @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
    @Html.ActionLink("Details", "Details", new { id=item.Id }) |
    @Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
4
  • Add cshtml code for your table to the question, please. Commented Feb 12, 2016 at 8:48
  • Use a view model containing only the 2 properties you want and add a [Display(Name = "Cuisine Name")] attribute Commented Feb 12, 2016 at 8:52
  • Hi Vadim Martynov, I added cshtml code. Commented Feb 12, 2016 at 9:17
  • Just to be clear on my question, if I refer Cusine name field in any other model, I need 'Cusine Name' as my label if it is in the views of 'Cusine' I need 'Name' as my label. Is there any way to do this without duplicating my validations by creating view model? Commented Feb 12, 2016 at 9:28

3 Answers 3

4

You can use DataAnnotation for this

public partial class Cuisine
{
    public int Id { get; set; }

    [Display(Name="Name of Cuisine")]
    public string Name { get; set; }

    public virtual ICollection<Dish> Dishes { get; set; }
}

EDIT:

You have used @Html.DisplayNameFor(model => model.Cuisine.Name) to display the name of Cuisine. You can use LabelFor() instead of DisplayNameFor to display the name. Change the cshtml and use

@Html.LabelFor(model =>  model.Cuisine.Name, "Cuisine Name")
Sign up to request clarification or add additional context in comments.

3 Comments

But in my Cuisine view, I want it as 'Name' only and in Dishes view I want it as 'Cuisine Name'. Adding data annotation changes name everywhere
Hey, thanks for the LabelFor attribute. but I am getting an error when I refer model.Cuisine as in above syntax. It shows that model.Cuisine is not present in the model. I am not getting any error in DisplayNameFor() attribute. It's confusing. Can you explain why this is happening?
Using LabelFor() is not appropriate - it create a <label> element which is an accessibility element associated with a form control and there are no form controls. It should be @Html.DisplayNameFor()
3

It would probably be a good idea to use a ViewModel, which aggregates just the properties you need for your view.

public class DishVm
{
        public int Id { get; set; }

        [Display(Name="Cuisine Name")]
        public string Name { get; set; }

        [Display(Name="Name")]
        public string DishName { get; set; }
}

I don't know how you are retrieving your data, but it would look similar to this:

IEnumerable<DishVm> vm = context.Dishes
                                .Include(c => c.Cuisines)
                                .OrderBy(n => n.Name)
                                .Select(x => new DisVm {
                                    Name = x.Cuisine.Name,
                                    DishName = x.Name
                                 });

return View(vm);

Your view would then have a new model type: @model IEnumerable<Yournamespace.Folder.DishVm>

7 Comments

But this way I have to duplicate all of my validations. My other fields have several validations. Also, I have a doubt that we loose navigation properties if we create ViewModel(Correct me if I am wrong). Is there any approach other than using ViewModel?
@aditya, Your not duplicating any validations. A [Display] attribute is a view specific attribute and should not be in a data model. Using a view model is the correct approach
So, If I have 10 other fields and each has some validation like email validation, some regular expression validation in my Model(Dish), should I write all those validations in my view model also? If yes, I am duplicating the work right?
@aditya, Your view is just display 2 properties. And your not editing anything so no validation attributes would be applied to the view model.
@stephen Muecke This helps for one scenario. But my worry is I have other views which have the same problem and I have to show 9 columns each using some validation. This is where my worry goes. If I create a view model for every view like this, I may end up creating validations for every view model.
|
0

On top of your virtual property, decorate it with a [Display(Name="Cuisine"]

Then in your view -> header, drop the .Name in the end. So it says: @Html.DisplayNameFor(model => model.Cuisine)

It's that simple :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.