将未使用的viewdata传递给MVC5中的每个页面是不是很糟糕(性能明智)?

时间:2015-02-16 08:42:20

标签: c# asp.net-mvc razor

所以我有一个支持多语言的站点,我使用ViewData来实现这一点,例如我有2个页面(Home和Register)。

查看:

Home.cshtml

<p>@ViewData("Home")</p>

Register.cshtml

<p>@ViewData("UserName")</p>
<p>@ViewData("EmailAddress")</p>

控制器:

public ActionResult Home()
{
     ViewData("Home") = GetLang("Home", langcode); //function to get the text(cached) based on language code like english, spanish, etc
     return View();
}

public ActionResult Register()
{
     ViewData("UserName") = GetLang("UserName", langcode);
     ViewData("EmailAddress") = GetLang("EmailAddress", langcode);
     return View();
}

我很难在每个页面中输入我需要的ViewData,所以我想的是如果我创建一个包含所有ViewData的方法并在每个ActionResult中调用它。

示例:

public void GetAllViewData(string langcode)
{
     ViewData("Home") = GetLang("Home", langcode);
     ViewData("UserName") = GetLang("Home", langcode);
     ViewData("EmailAddress") = GetLang("EmailAddress", langcode);
}

控制器

public ActionResult Home()
{
     GetAllViewData(langcode);
     return View();
}

public ActionResult Register()
{
     GetAllViewData(langcode);
     return View();
}

性能是否差(所有文本都缓存在AppStart上)?因为“UserName”和“EmailAddress”ViewData未在HomePage中使用。

对于糟糕的英语,任何帮助都会受到赞赏和抱歉。

2 个答案:

答案 0 :(得分:1)

如果您对某些页面中可能未使用的语言特定属性的昂贵评估得到了肯定,您可以尝试创建一个具有空状态和惰性getter的自定义模型,并使用`ViewBag访问它。

public class AppModel
{
    private readonly string _lang;

    public AppModel(string lang)
    {
        _lang = lang;
    }

    public string Home { get { return GetLanguageSpecific("Home"); } }

    public string UserName { get { return GetLanguageSpecific("UserName"); } }

    public string EmailAddress { get { return GetLanguageSpecific("Email Address"); } }

    private string GetLanguageSpecific(string key)
    {
        // fake implementation.
        return string.Format("Requested a string: {0} for language: {1}", key, _lang);
    }
}

然后,实现一个基本控制器类,它在ViewBag中设置共享数据(ViewBag只是​​带有动态表示法的ViewData的包装器),并从中派生出控制器类:

 public class CommonAppController : Controller
 {
     protected CommonAppController()
     {
         ViewBag.Common = new AppModel("en");
     }
 }

 public class RegisterController : CommonAppController
 { //...

现在您可以在视图中编写以下内容:

 <p>@ViewBag.Common.UserName</p>

这样,只有在请求时才会评估属性,并且您只有一个AppModel类型的廉价对象,而且每个控制器实例都没有创建状态。

更新:我的CommonAppController代码出错。应该是ViewBag.Common,而不是ViewBag["Common"]

答案 1 :(得分:0)

它会影响性能,但影响不大(当然假设GetLang方法调用费用不高)。

您可以将视频模型用于在需要时获取数据的视图,而不是将数据放在ViewData中:

public class LanguageModel {

  private int _langcode;

  public LanguageModel(int langcode) {
    _langcode = langcode;
  }

  public string this[string name] {
    get {
      return GetLang(name, _langcode);
    }
  }

}

在操作方法中,您可以使用语言代码为每个视图创建模型:

public ActionResult Home() {
 return View(new LanguageModel(langcode));
}

public ActionResult Register() {
 return View(new LanguageModel(langcode));
}

在视图中,您可以在@Page标记中指定模型的类型,例如:

Inherits="System.Web.Mvc.ViewPage<MyApp.LanguageModel>

然后在视图中,您将使用Model["Home"]代替ViewData("Home")