MVC Razor WebGrid Nullable Complex Types
I have an entity called 开发者_如何学GoLookup who has a complex Type Description with two string English and French. There has arise a time where no value will be store into the lookup. Now other entities have lookups as properties so we could have foo.Lookup.Description.English for example.
I'm trying to use a Web Grid to display the information being selected.
Originally my controller looked like
public ViewResult Index()
{
var foos = db.Foos;
return View(foo.ToList());
}
and my view looked like
@model IEnumerable<Foo>
@{
ViewBag.Title = "Index";
}
<h2>Stay Manager</h2>
@{
var grid = new WebGrid(Model, defaultSort: "sortMe", rowsPerPage: 3);
grid.GetHtml(htmlAttributes: new { id = "DataTable" });
}
@grid.GetHtml(columns: grid.Columns(
grid.Column("Lookup.Description.English", "Column Header")
))
My issue is that Lookup can at times be null and ill will get an error saying the the Column Lookup.Description.English does not exist.
I found a solution but not a very elegant one and was hoping that there was a better a way. My solution was to change my controller action to
public ViewResult Index()
{
var foos = db.Foos;
foreach (Foo currentFoo in Foos.Where(s => s.Lookup == null))
{
Foo.Lookup = new Lookup();
Foo.Lookup.Description.English = "";
Foo.Lookup.Description.French = "";
}
return View(foos.ToList());
}
Any suggestions on how to get the Web Grid to work better with null-able complex types?
Not at all that familair with webgrid, but would the following be a solution for you? I made the following simple model:
public class Foo
{
public string Name { get; set; }
public Lookup Lookup { get; set; }
}
public class Lookup
{
public string Name { get; set; }
public Description Description { get; set; }
}
public class Description
{
public string English { get; set; }
public string French { get; set; }
}
controller action (i don't have a db, so I mocked some data):
public ViewResult Index()
{
//var foos = db.Foos;
var foos = new List<Foo>();
foos.Add(new Foo { Name = "Foo1" });
foos.Add(new Foo
{
Name = "Foo2",
Lookup = new Lookup
{
Name = "Lookup2",
Description = new Description
{
English = "englishFoo2",
French = "frenchFoo2"
}
}
});
foos.Add(new Foo
{
Name = "Foo3",
Lookup = new Lookup
{
Name = "Lookup3",
Description = new Description
{
//English = "englishFoo3",
French = "frenchFoo3"
}
}
});
foos.Add(new Foo { Name = "Foo4" });
foos.Add(new Foo
{
Name = "Foo5",
Lookup = new Lookup
{
Description = new Description
{
English = "englishFoo5",
French = "frenchFoo5"
}
}
});
foos.Add(new Foo {
Name = "Foo6",
Lookup = new Lookup
{
Name = "Lookup6"
}
});
return View(foos);
}
So, I now have Foos with or without Lookups (with or without Description).
The view is as follows:
@model IEnumerable<Foo>
@{
var grid = new WebGrid(Model, defaultSort: "sortMe", rowsPerPage: 10);
grid.GetHtml(htmlAttributes: new { id = "DataTable" });
}
@grid.GetHtml(
columns: grid.Columns(
grid.Column(
columnName: "Name",
header: "Foo"
),
grid.Column(
columnName: "Lookup.Name",
header: "Lookup",
format: @<span>@if (item.Lookup != null)
{ @item.Lookup.Name }
</span>
),
grid.Column(
columnName: "Lookup.Description.English",
header: "Description.English",
format: @<span>@if (item.Lookup != null && item.Lookup.Description != null)
{ @item.Lookup.Description.English }
</span>
),
grid.Column(
columnName: "Lookup.Description.French",
header: "Description.French",
format: @<span>@if (item.Lookup != null && item.Lookup.Description != null)
{ @item.Lookup.Description.French }
</span>
)
)
)
which works just fine for me (Asp.Net MVC 3), it procudes the following html:
[snip]
<tr>
<td>Foo4</td>
<td><span></span></td>
<td><span></span></td>
<td><span></span></td>
</tr>
<tr>
<td>Foo5</td>
<td><span></span></td>
<td><span>englishFoo5 </span></td>
<td><span>frenchFoo5 </span></td>
</tr>
<tr>
<td>Foo6</td>
<td><span>Lookup6</span></td>
<td><span></span></td>
<td><span></span></td>
</tr>
[/snip]
精彩评论