我目前正在实施一个本地化的网站。我创建了一个自定义 ResourceProvider + Factory 用于将资源存储在数据库中。这一切都有效,我存储数据如下:
resourceid | url (null) | type (null) | name | culture (null) | value
1 | NULL | Common | Test | NULL | Hi
2 | ~/Views/Products/Index.aspx | NULL | Products | NULL | Products
如果我是正确的,我已经在上面的示例中存储了一个全局(测试)和一个本地(产品)资源?
我正在使用 ResourceHelpers 的这个实现(链接)(下面的代码)。这应该允许我根据以下代码显示资源:
全局资源:这有效(输出:“Hi”)
<% =Html.Resource("Common, Test") %>
本地资源:这是问题所在,这不起作用,这是怎么回事??
<% =Html.Resource("Products") %>
第一个代码示例按预期输出“Hi”。但是,第二个代码示例引发异常(未找到具有键“产品”的资源对象。)(我已在代码中标记了 ~ 第 17 行下方的行)。 是的,我正在调用“~/Views/Products/Index.aspx”的第二行
这是我正在使用的助手代码:
<System.Runtime.CompilerServices.Extension()> _
Public Function Resource(ByVal htmlhelper As HtmlHelper, ByVal expression As String, ByVal ParamArray args As Object()) As String
Dim virtualPath As String = GetVirtualPath(htmlhelper)
Return GetResourceString(htmlhelper.ViewContext.HttpContext, expression, virtualPath, args)
End Function
<System.Runtime.CompilerServices.Extension()> _
Public Function Resource(ByVal controller As Controller, ByVal expression As String, ByVal ParamArray args As Object()) As String
Return GetResourceString(controller.HttpContext, expression, "~/", args)
End Function
Private Function GetResourceString(ByVal httpContext As HttpContextBase, ByVal expression As String, ByVal virtualPath As String, ByVal args As Object()) As String
Dim context As New ExpressionBuilderContext(virtualPath)
Dim builder As New ResourceExpressionBuilder()
'The following line throws the exception
Dim fields As ResourceExpressionFields = DirectCast(builder.ParseExpression(expression, GetType(String), context), ResourceExpressionFields)
If Not String.IsNullOrEmpty(fields.ClassKey) Then
Return String.Format(DirectCast(httpContext.GetGlobalResourceObject(fields.ClassKey, fields.ResourceKey, CultureInfo.CurrentUICulture), String), args)
End If
Return String.Format(DirectCast(httpContext.GetLocalResourceObject(virtualPath, fields.ResourceKey, CultureInfo.CurrentUICulture), String), args)
End Function
Private Function GetVirtualPath(ByVal htmlhelper As HtmlHelper) As String
Dim virtualPath As String = Nothing
Dim controller As Controller = TryCast(htmlhelper.ViewContext.Controller, Controller)
If controller IsNot Nothing Then
'Dim result As ViewEngineResult = FindView(controller.ControllerContext, htmlhelper.ViewContext.ViewName)
Dim result As ViewEngineResult = FindView(controller.ControllerContext, GetViewName(htmlhelper.ViewContext.View))
Dim webFormView As WebFormView = TryCast(result.View, WebFormView)
If webFormView IsNot Nothing Then
virtualPath = webFormView.ViewPath
End If
End If
Return virtualPath
End Function
Private Function FindView(ByVal controllerContext As ControllerContext, ByVal viewName As String) As ViewEngineResult
' Result
Dim result As ViewEngineResult = Nothing
' Search only for WebFormViewEngine
Dim webFormViewEngine As WebFormViewEngine = Nothing
For Each viewEngine In ViewEngines.Engines
webFormViewEngine = TryCast(viewEngine, WebFormViewEngine)
If webFormViewEngine IsNot Nothing Then
Exit For
End If
Next
result = webFormViewEngine.FindView(controllerContext, viewName, "", False)
If result.View IsNot Nothing Then
result = webFormViewEngine.FindPartialView(controllerContext, viewName, False)
End If
' Return
Return result
End Function
Private Function GetViewName(ByVal view As IView) As String
Dim viewName As String = Nothing
If TypeOf view Is WebFormView Then
viewName = Path.GetFileNameWithoutExtension((DirectCast(view, WebFormView)).ViewPath)
End If
Return viewName
End Function