gpt4 book ai didi

c# - asp.net mvc 3 razor view -> strongly typed List of tuple 问题

转载 作者:IT王子 更新时间:2023-10-29 04:02:36 28 4
gpt4 key购买 nike

我在使用 asp.net MVC razor View 时遇到了一个奇怪的问题。

我希望我的模型是 List<Tuple<string, int, int, int, int>>,这在我的其他 C# 方法中完全有效。但是当我将它粘贴到 @model 声明中时,它似乎只挑选出元组的字符串部分。所以我没有整数。只有 item1.

如果我让它绑定(bind)到一个元组而不是列表,这个问题就不存在了。

似乎生成的代码是错误的,所以这可能是 razor view 中的错误?

我在编译时得到的错误是:

Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately. 

Compiler Error Message: CS1003: Syntax error, '>' expected

Source Error:


Line 27:
Line 28:
Line 29: public class _Page_Views_Dashboard_DestinationStatistics_cshtml : System.Web.Mvc.WebViewPage<List<Tuple<string {
Line 30:
Line 31: #line hidden

为了隔离这个问题,我做了以下事情:

创建一个空的 asp.net mvc 项目。创建新 View 。粘贴以下代码。

@model List<Tuple<string, int, int, int, int>>

@foreach (var stat in Model)
{
<tr>
<td>
@stat.Item1
</td>
<td>
@stat.Item2
</td>
<td>
@stat.Item3
</td>
<td>
@stat.Item4
</td>
<td>
@stat.Item5
</td>
</tr>
}

我知道我可以创建一个类或结构来保存数据。只是出于好奇而问

编辑:在这里解决并报告给 MVC 团队 http://aspnet.codeplex.com/workitem/8652

最佳答案

编辑我在这里删除了一些正在进行的评论 - 只需查看历史记录即可。

因此,您可以使用 1、2、3 或 4 个元组通用参数使其工作,但不适用于 5 个元组参数。一旦您使用 5 个参数,它就会生成如下代码:

 public class _Page_Views_Home_Index_cshtml : 
System.Web.Mvc.WebViewPage<List<System.Tuple<string {

我只是想知道它是否是字符长度限制,所以我生成了一个这样的类:

namespace ASP{  //same namespace that the backend code for the page is generated
public class T { }
}

并更改了模型声明:

@model List<Tuple<T,T,T,T,T>>.

最后(查看历史记录)我得到了

@inherits System.Web.Mvc.WebViewPage<Tuple<T,T,T,T,T>>

同样的问题! @model 关键字不是问题...

花了一段时间(阅读了 MVC3 和 Razor 源代码,向该解决方案添加了几个测试)- 但这里有一个测试说明了为什么我们会收到此错误:

[TestMethod]
public void TestMethod()
{
System.CodeDom.CodeTypeReferenceCollection c =
new CodeDom.CodeTypeReferenceCollection();
c.Add("Tuple<T,T,T,T>");
c.Add("Tuple<T,T,T,T,T>");
//passes
Assert.AreEqual("Tuple<T,T,T,T>", c[0].BaseType);
//fails
Assert.AreEqual("Tuple<T,T,T,T,T>", c[1].BaseType);
}

因此 - 四参数版本通过,但 5 参数版本未通过。

猜猜看 - 实际值为 Tuple<T - 即截断的通用类型名称​​截断方式与您在代码中观察到的完全相同

标准 Razor 解析器和 Mvc Razor 解析器都使用 CodeTypeReferenceCollection解析 @inherits 时输入或 @model关键词。这是 @inherits 的代码在代码生成期间:

protected internal virtual void VisitSpan(InheritsSpan span) {
// Set the appropriate base type
GeneratedClass.BaseTypes.Clear();
GeneratedClass.BaseTypes.Add(span.BaseClass);

if (DesignTimeMode) {
WriteHelperVariable(span.Content, InheritsHelperName);
}
}

GeneratedClass.BaseTypesCodeTypeReferenceCollection - 和 span.BaseClass是一个字符串。在 ILSpy 之后,违规方法必须是私有(private)方法 CodeTypeReference.Initialize(string typeName, CodeTypeReferenceOptions options) .我现在没有足够的时间弄清楚它为什么会崩溃 - 但我认为这是 Microsoft 开发人员的工作:) 下面的更新 - 无法抗拒。我现在知道哪里错了

底线

您不能在 Razor 中使用超过 4 个参数的泛型 @inherits@model语句(至少在 C# 中——不知道 VB)。看起来 Razor 解析器错误地使用了 CodeTypeReference类型。

最终更新 - 或者,我咬牙切齿:)

其中一件事CodeTypeReference确实是通过调用方法 CodeTypeReference.RipOffAssemblyInformationFromTypeName(string typeName) 从传递的类型名称中剥离程序集名称信息。 .

当然,如果您考虑一下 - Tuple<T,T,T,T,T>就像一个程序集限定的类型名称:类型名称 = Tuple<T , 组装 = T , 版本= T , 文化= T , 公钥 token = T (如果你写了一个非常糟糕的 C# 解析器!)。

果然 - 如果你传入 Tuple<T,T,T,T,T,T>作为类型名称 - 你实际上得到一个 Tuple<T,T> .

深入研究代码,它已准备好接收语言中立的类型名称(例如,处理“[”但不处理“<”)因此,实际上,MVC 团队不应该只是将 C# 类型名称从我们的来源直接通过。

MVC 团队需要改变他们生成基本类型的方式 - 他们可以使用 public CodeTypeReference(string typeName, params CodeTypeReference[] typeArguments)新引用的构造函数(而不是仅仅依赖 .Add(span.BaseClass) 创建它),并自己解析泛型参数,因为他们知道类型名称将是 C#/VB 风格——而不是语言中立的 .Net 风格,带有方括号等实际姓名的一部分。

关于c# - asp.net mvc 3 razor view -> strongly typed List of tuple 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6098649/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com