Asp.net mvc 在处理完全合法的DBNULL时遇到困难。使用作为模型数据视图传递的数据集数据表。ASP.NET MVC2
我很喜欢MVC,但不幸的是,所有教程、演示和所有资源都使用实体框架来生成ViewData,并且大多数使用LINQ to SQL而不是数据集。Asp.net mvc 在处理完全合法的DBNULL时遇到困难。使用作为模型数据视图传递的数据集数据表。ASP.NET MVC2,asp.net-mvc,asp.net-mvc-2,exception,dbnull,dataset-designer,Asp.net Mvc,Asp.net Mvc 2,Exception,Dbnull,Dataset Designer,我很喜欢MVC,但不幸的是,所有教程、演示和所有资源都使用实体框架来生成ViewData,并且大多数使用LINQ to SQL而不是数据集。 我正在重用现有的业务逻辑,而客户机(他本身就是一名出色的编码员)希望继续使用数据集。。。所以我不能离开这些 我有一个表,其中包含数据库中允许为NULL的列。当我尝试访问这些…甚至检查它是否为空时,我会得到一个异常: <Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _ G
我正在重用现有的业务逻辑,而客户机(他本身就是一名出色的编码员)希望继续使用数据集。。。所以我不能离开这些 我有一个表,其中包含数据库中允许为NULL的列。当我尝试访问这些…甚至检查它是否为空时,我会得到一个异常:
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")> _
Public Property FNN_CARRIERS_DESC() As String
Get
Try
Return CType(Me(Me.tableVIT_FNN_CommsService.FNN_CARRIERS_DESCColumn),String)
Catch e As Global.System.InvalidCastException
Throw New Global.System.Data.StrongTypingException("The value for column 'FNN_CARRIERS_DESC' in table 'VIT_FNN_CommsService' is DBNul"& _
"l.", e)
End Try
End Get
Set
Me(Me.tableVIT_FNN_CommsService.FNN_CARRIERS_DESCColumn) = value
End Set
End Property
“表'FNN_CARRIERS_DESC'中'FNN_CARRIERS_DESC'列的值为DBNull”
现在,这是由dataset.designer.vb文件生成的
我知道你要说什么。“FNN_品牌为空!!!”
这是真的。
但是…遵循堆栈跟踪,代码中生成此错误的行是:
<%= Html.TextBox("FNN_CARRIERS_DESCTextBox", If(IsNothing(Model.FNN_CARRIERS_DESC), Model.FNN_CARRIERS_DESC, ""))%>
非常感谢您的指导!我的直觉告诉我这不是一个严格意义上的MVC问题,但可能是一些我对数据集不了解的问题
这是reference.vb文件中引发异常的代码:
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")> _
Public Property FNN_CARRIERS_DESC() As String
Get
Try
Return CType(Me(Me.tableVIT_FNN_CommsService.FNN_CARRIERS_DESCColumn),String)
Catch e As Global.System.InvalidCastException
Throw New Global.System.Data.StrongTypingException("The value for column 'FNN_CARRIERS_DESC' in table 'VIT_FNN_CommsService' is DBNul"& _
"l.", e)
End Try
End Get
Set
Me(Me.tableVIT_FNN_CommsService.FNN_CARRIERS_DESCColumn) = value
End Set
End Property
_
公共属性FNN_CARRIERS_DESC()作为字符串
得到
尝试
返回CType(Me(Me.tableVIT\u FNN\u CommsService.FNN\u CARRIERS\u DESCColumn),字符串)
捕获e为Global.System.InvalidCastException
抛出新的Global.System.Data.StrongTypingException(“表'VIT_FNN_CommsService'中'FNN_CARRIERS_DESC'列的值为DBNul”&
“l.”,e)
结束尝试
结束
设置
Me(Me.tableVIT\u FNN\u CommsService.FNN\u CARRIERS\u DESCColumn)=值
端集
端属性
我尝试过的事情:
- 注释掉异常将使其返回null,这正是我想要的,但当表更改或生成表结果的存储过程更改时,将重新生成数据集
- 更改了datatable上列的规则。实际上没有产生任何结果,并且在重新生成表时也将被覆盖
- IsNothing(列)或isDBnull(列)实际上会导致错误,因为正在检索和强制转换列
帮帮我,书呆子们。。。你是我唯一的希望 好的,您有一些依赖于数据集的现有数据访问逻辑。这很好(想想它可能会像VB6:-)那样糟糕得多)。我们都必须处理遗留代码。这很正常。遗留代码无处不在 虽然这并不是用它污染你的新MVC应用程序的原因。这就是我给你的建议。将这些遗留代码封装到一些只适用于强类型的外部存储库中。例如:
Public Interface IProductsRepository
Function GetProduct(id As Integer) As Product
End Interface
然后实施:
Public Class LegacyProductsRepository
Implements IProductsRepository
Public Function GetProduct(id As Integer) As Product
' TODO: call your legacy code here and convert the datasets
' and datatables you were dealing with into a nice strongly
' typed model object
End Function
End Class
现在,您的控制器不应该听到数据集和类似的废话:
Public Class ProductsController
Inherits Controller
Private ReadOnly _repository As IProductsRepository
Public Sub New(repository As IProductsRepository)
_repository = repository
End Sub
Public Function Show(id As Integer) As ActionResult
Dim product = _repository.GetProduct(id)
Return View(product)
End Function
End Class
你看。现在一切都干净简单了。您的视图与强类型产品对象一起工作,不应处理数据集和数据表,并且您描述的异常永远不会发生:-)好,因此您有一些依赖于数据集的现有数据访问逻辑。这很好(想想它可能会像VB6:-)那样糟糕得多)。我们都必须处理遗留代码。这很正常。遗留代码无处不在 虽然这并不是用它污染你的新MVC应用程序的原因。这就是我给你的建议。将这些遗留代码封装到一些只适用于强类型的外部存储库中。例如:
Public Interface IProductsRepository
Function GetProduct(id As Integer) As Product
End Interface
然后实施:
Public Class LegacyProductsRepository
Implements IProductsRepository
Public Function GetProduct(id As Integer) As Product
' TODO: call your legacy code here and convert the datasets
' and datatables you were dealing with into a nice strongly
' typed model object
End Function
End Class
现在,您的控制器不应该听到数据集和类似的废话:
Public Class ProductsController
Inherits Controller
Private ReadOnly _repository As IProductsRepository
Public Sub New(repository As IProductsRepository)
_repository = repository
End Sub
Public Function Show(id As Integer) As ActionResult
Dim product = _repository.GetProduct(id)
Return View(product)
End Function
End Class
你看。现在一切都干净简单了。您的视图使用强类型产品对象,不应处理数据集和数据表,您描述的异常也不应发生:-)如果有人感兴趣,我找到了更好的解决方案。。。一个可以让你继续使用中间层没有数据集的数据集。 列是可以为空的。数据集实际上为您提供了一个方法
Model.isFNN_CARRIERS_DESCNull()
因此可以检查此列的可空性…而不会导致崩溃。如果有人感兴趣,我会找到更好的解决方案。。。一个可以让你继续使用中间层没有数据集的数据集。 列是可以为空的。数据集实际上为您提供了一个方法
Model.isFNN_CARRIERS_DESCNull()
因此,可以检查此列的可空性…而不会导致崩溃。虽然Korz在向客户解释时可能想重新表述解决方案,但这绝对是一个好建议;-)酷,好吧,这就是所谓的视图模型吗?@korz,不完全是。视图模型位于模型(本例中为产品)和视图之间。它是一个专门为给定视图的需要而定制的类。因此,例如,如果您的产品模型包含10个属性,但您只想在视图上显示其中的两个属性,并且需要对它们进行特定的格式化,那么您可以编写一个ProductViewModel类。然后,控制器在产品模型和视图模型之间映射,并将视图模型传递给视图。在我的示例中,我将模型直接传递给视图,这是一种不好的做法,但对于这里的目的来说已经足够了。干杯!你们太棒了!我会告诉你我的进展!虽然Korz在向客户解释解决方案时可能会想重新措辞,但这绝对是一个很好的建议;-)酷,好吧,这就是所谓的视图模型吗?@korz,不完全是。视图模型位于模型(本例中为产品)和视图之间。它是一个专门为给定视图的需要而定制的类。例如,如果您的产品模型包含10个属性,但您只想在视图中显示其中的两个属性,则需要对它们进行修改