Asp.net mvc 根据模型中的特性显示不同的图像

Asp.net mvc 根据模型中的特性显示不同的图像,asp.net-mvc,Asp.net Mvc,我需要根据属性的特定值显示不同的图像。 这是我完成这项任务的方法 我有一个模型: public class DetailInfoViewModel { public string Status {get; set;} public string StatusImageName {get; set;} ... other fields } 在行动中: var model = ...// create view model and fill properties m

我需要根据属性的特定值显示不同的图像。
这是我完成这项任务的方法

我有一个模型:

public class DetailInfoViewModel
{
    public string Status {get; set;}
    public string StatusImageName {get; set;}
    ... other fields
}
在行动中:

var model = ...// create view model and fill properties    
model.StatusImageName = GetImageFileNameForStatus(model.Status.ToLower());
主要方法是:

private string GetImageFileNameForStatus(string status)
{
    if (status == "payed" || status == "approved")
        return "payed.png";

    if (status == "printed")
        return "not-pay.png";

    if (status == "closed")
        return "closed.png";

    if (status == "transfer")
        return "transfer.png";

    return string.Empty;
}
在视图中,我有简单的html:

<div class="pull-right">
    <img src="@Url.Content("~/Images/" + Model.StatusImageName)"/>
</div>

但这条路很难看。如果重命名图像或打印错误,则此代码将无法正常工作。

有更好的办法吗

我不知道这是最好的方法,但我的意思是,你可以将imageName定义为状态名

status | statusImage |
----------------------
 payed |   payed.png |
closed |  closed.png |
   ... |         ... |
然后



<代码> > p>为了使其不易出错,请考虑使状态为EnUM

enum Status { Payed, Printed, Closed, Approved, Transfer}
并用于生成指向资源的强链接:

private string GetImageFileNameForStatus(Status status)
{
    switch(status){
      case Payed:
      case Approved:
        // This is generated by T4MVC for you
        return Links.Content.Images.payed_png;
      case Printed:
        return Links.Content.Images.not_pay_png;          
      // ... etc.
      default:
        return Links.Content.Images.default_png;
    }
}
您可以将信息保存在
字典
中,而不是switch语句,但这是一个实现细节

然后,您可以使用与此类似的:

<img src="@Model.StatusImageName" alt="@Model.Status"/>
还有你的模特:

public class DetailInfoViewModel
{
  ... 
  public IStatus Status{get;set;}
}
在你看来:

<img src="@Model.Status.InfoImage" alt="Status"/>

如果存在特定于给定状态的事物,这种方法甚至更好。您可以将与特定状态相关的所有内容整齐地封装在各自的IStatus实现中

同样,从面向对象设计的角度来看,UI细节(要显示的图像)成为模型的一部分感觉很奇怪。另一方面,它是一个视图模型,为什么不呢。如果你想去死OOP和系统复杂性和要求保证它,你可以考虑():< /P>
用户界面{
T VisitPaydStatus(付款人状态);
T打印状态(打印状态状态);
// ...
}
界面状态{
不接受(访客);
}
类别PayedStatus:IStatus{
公众不接受(ISTATUS访客){
回访访客。访问被访问状态(本);
}
}
类PrintedStatus:IStatus{
公众不接受(ISTATUS访客){
return visitor.VisitPrintedStatus(此);
}
}
类InfoImageVisitor:IStatusVisitor{
公共字符串VisitPaydStatus(PaydStatus状态){
返回Links.Content.Images.payed_png;
}
公共字符串VisitPrintedStatus(打印状态){
返回Links.Content.Images.not\u pay\u png;
}
}
通过这种方式,您可以将有关info映像的所有内容从state类移到单独的类中

但正如我所说,这已经可以被认为是一个过度工程的例子。这取决于系统的要求


总而言之:关于设计模式的内容绝对值得一读。

谢谢你的回答。但我认为解决方案过于复杂,正如我所说的,状态模式和访问者模式可能是多余的,但是考虑EnUM+T4MVC方法。它将帮助您在编译时捕获错误。
public class DetailInfoViewModel
{
  ... 
  public IStatus Status{get;set;}
}
<img src="@Model.Status.InfoImage" alt="Status"/>
interface IStatusVisitor<T>{
   T VisitPayedStatus<T>(PayedStatus status);
   T PrintedStatus<T>(PrintedStatus status);
   // ...
}

interface IStatus{
    T Accept(IStatusVisitor<T> visitor);
}

class PayedStatus : IStatus {    
    public T Accept(IStatusVisitor<T> visitor){
        return visitor.VisitPayedStatus(this);
    }
}

class PrintedStatus : IStatus {    
    public T Accept(IStatusVisitor<T> visitor){
        return visitor.VisitPrintedStatus(this);
    }
}


class InfoImageVisitor : IStatusVisitor<string>{

  public string VisitPayedStatus(PayedStatus status){
    return Links.Content.Images.payed_png;
  }

  public string VisitPrintedStatus(PrintedStatus status){
    return Links.Content.Images.not_pay_png;
  }

}


<img src="@Model.Accept(new InfoImageVisitor())" alt="Status"/>