user1079925
user1079925

Reputation: 541

mvc3 .net Display View Template using Html.DisplayFor

I'm trying to use templates.

I'm having trouble using using the Html.DisplayFor extension

I want the template to display all the data as read-only. I believe that HTML.DisplayFor can do this?

If this is so, I have a IEnumerable model being passed to the view:

@model IEnumerable<Tens.Models.Applicant>

@{   
    if (Model != null)
    {  
          @Html.DisplayForModel("ApplicationOutcome") 
    } 
 }

and my Template:

@model IEnumerable<Tens.Models.Applicant>

@{

foreach(var item in Model)
{
    @Html.TextBox("forenames",item.Forenames)
    <br />
    @Html.TextBox("surname",item.Surname)
    <br />
    <text>----------------------------------</text>
    <br>
}
}

The above code works fine (2 records displayed) but it would mean me setting each fields readonly attribute to true (there are a load more fields - so tedious). What I want to do is use Html.DisplayFor to display this data as readonly, but I've tried numerous different ways and can't get it to work. Any help is appreciated.

Upvotes: 0

Views: 2007

Answers (3)

Erik Funkenbusch
Erik Funkenbusch

Reputation: 93434

Your code is quite strange. Here is how I would do it.

WhateverView.cshtml

@model IEnumerable<Tens.Models.Applicant>  

@Html.DisplayForModel()

Then, in the DisplayTemplate folder:

Applicant.cshtml

@model Tens.Models.Applicant

@Html.LabelFor(m => Forenames)
@Html.DisplayFor(m => m.Forenames)

@Html.LabelFor(m => Surnames)
@Html.DisplayFor(m => m.Surnames)

etc.. The key to using a template like this where your model is a collection is that the template only works with a single item (note there is no IEnumerable in the template).

Upvotes: 1

Anil Ali
Anil Ali

Reputation: 478

You should take a look at this article by Brad Wilson if you want to know more on this. http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-3-default-templates.html Basically the issue you are seeing is due to this check in the default display template for type object

ViewData.TemplateInfo.TemplateDepth > 1

Rather than calling

@Html.DisplayForModel("ApplicationOutcome") 

in your view which calls another template. Put

foreach(var item in Model)
{
    @Html.DisplayFor(m=>item)
}

in your view directly. This should get you the expected result.

Below are my MVC Controller/Model/View files. Can you try with these. I don't have any templates files specific to the model which is the key. What will happen is mvc will use the default template to render that object.

DefaultController.cs (controller)

public class DefaultController : Controller
{
    //
    // GET: /Default/

    public ActionResult Index()
    {
        var model = new List<Applicant>();
        model.Add(new Applicant{FirstName = "foo",LastName = "bar", Address = "Foo Bar"});
        model.Add(new Applicant { FirstName = "foo1", LastName = "bar1", Address = "Foo1 Bar1" });
        model.Add(new Applicant { FirstName = "foo2", LastName = "bar2", Address = "Foo2 Bar2" });

        return View(model);
    }
}

Application.cs (model)

public class Applicant
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address { get; set; }
}

Index.cshtml (view)

@model IEnumerable<MvcApplication1.Models.Applicant>
@{
    Layout = null;
}
<html>
   <head>
     <title>this is a test</title>
   </head>
<body>
    <h1>This is a test</h1>
    @if (Model != null)
    {
        foreach (var item in Model)
        {
            @Html.DisplayFor(m => item)
            <br/>
        }
    }
</body>

Result Output

Result

Upvotes: 0

user1079925
user1079925

Reputation: 541

I found that if I do the following in the template I get the data as expected:

@model IEnumerable<Tens.Models.Applicant>

@{

foreach(var item in Model)
{
    @Html.DisplayFor(m=>item.Forenames)
    <br />
    @Html.DisplayFor(m=>item.Surname)
    <br />
    <text>----------------------------------</text>
<br />
}
}

Upvotes: 0

Related Questions