Skip to main content
 首页 » 编程设计

c#之MVC Razor WebGrid 可空复杂类型

2024年02月23日35lyj

我有一个名为 Lookup 的实体,它有一个复杂的类型描述,包含两个字符串英语和法语。出现了没有值将存储到查找中的时间。现在其他实体将查找作为属性,因此我们可以使用 foo.Lookup.Description.English 例如。

我正在尝试使用 Web 网格来显示所选择的信息。

原来我的 Controller 是这样的

    public ViewResult Index() 
    { 
        var foos = db.Foos; 
 
        return View(foo.ToList()); 
    } 

我的观点看起来像

@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") 
)) 

我的问题是 Lookup 有时可能为 null,我会收到一条错误消息,指出 Column Lookup.Description.English 不存在。

我找到了一个解决方案,但不是一个非常优雅的解决方案,希望有更好的方法。我的解决方案是将我的 Controller 操作更改为

    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()); 
    } 

关于如何使 Web 网格更好地处理可为 null 的复杂类型有什么建议吗?

请您参考如下方法:

对 webgrid 一点也不熟悉,但以下是适合您的解决方案吗? 我制作了以下简单模型:

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 操作(我没有数据库,所以我模拟了一些数据):

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); 
} 

因此,我现在拥有带或不带查找(带或不带描述)的 Foos。

View 如下:

@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> 
    ) 
) 
) 

这对我来说工作得很好(Asp.Net MVC 3),它产生了以下 html:
[剪]

<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]