如何避免在MVC核心视图的条件代码中对业务实体的值进行硬编码?

时间:2019-04-21 04:35:25

标签: asp.net-core-mvc ef-core-2.0

当我想基于数据库中的某些主表值显示特定的局部视图(或其他一些客户端代码)时,我在视图中的许多代码似乎采用以下形式-

<div id="@claim.Id" class="ReimbursementClaims">
    @if (claim.ClaimStatus.SubmissionStatus == "Unsubmitted")
        {
            <partial name="~/Views/Claims/_ClaimDetailsEditor.cshtml" />
        }
    else (claim.ClaimStatus.SubmissionStatus == "Approved")
        {
            <partial name="~/Views/Claims/_ClaimDetailsReadonly.cshtml" />
        }
</div>

后端数据库包含一个Claim表和一个相关的ClaimStatusMaster表。 ClaimStatusMaster表是一个主表,这意味着它仅用于存储静态值(如“已批准”,“未提交”)。例如-

create table Claim (Id int, ClaimStatusId int) --ClaimStatusId is a foreignkey linking to ClaimStatusMaster
create table ClaimStatusMaster (id int, SubmissionStatus varchar(20))
insert into ClaimStatusMaster values (2, 'Unsubmitted')
insert into ClaimStatusMaster values (1, 'Approved')
insert into ClaimStatusMaster values (3, 'Rejected') --etc

如您所见,要完全显示的适当视图取决于ClaimStatusMaster表的SubmissionStatus字段的值。但是,如果SubmissionStatus出于任何原因发生变化,则视图中的ifelse条件将被破坏。因此,我试图找出如何对此进行更好地编码,以最大程度地减少这种耦合,同时还能够基于SubmissionStatus值有条件地显示适当的视图。我该如何实现?

PS:我可能可以将ifelse代码放在控制器中,但这似乎导致或多或少的相同问题。

2 个答案:

答案 0 :(得分:1)

在大多数情况下,我会避免在视图中加入任何逻辑。但是,我认为像您这样的简单逻辑可以根据控制器传递给它的某些属性来选择其他表示形式。

话虽这么说,一种替代方法是创建一个处理该逻辑的扩展方法。您要做的就是调用扩展名,它将返回部分的全名。

答案 1 :(得分:0)

一种可能的方法是在您的逻辑中直接使用ClaimStatusId。您可以创建Enum:

public enum SubmissionStatus
{
    Approved = 1 ,
    Unsubmitted =2 ,
    Rejected =3 ,
}

然后在视图中编写逻辑:

<div id="@claim.Id" class="ReimbursementClaims">
@if ((int)claim.ClaimStatusId  == (int)SubmissionStatus.Unsubmitted)
{
    <partial name="~/Views/Claims/_ClaimDetailsEditor.cshtml" />
}

但是,您当然应该将枚举值与数据库ClaimStatusMaster值进行同步。