当您从 ASP.NET MVC Preview 5 升级到新发布的Beta版本时,您需要做哪些问题或重构?
19 回答
问题一:黄屏死机。
CS0234: The type or namespace name 'Mvc' does not exist in the namespace 'System.Web' (are you missing an assembly reference?)
解决方案:我删除了我项目中的所有引用并重新添加它们,指向程序文件\asp.net\asp.net mvc beta\assemblies中的程序集,但这并没有解决问题。
我在 gac 中有一个 system.web.mvc dll(不知道如何)。试图删除它。无法;一个或多个应用程序需要组装。必须按照此处所述找到程序集并删除注册表项。然后我能够删除 gac 的 system.web.mvc 版本。
这仍然没有解决问题。我不得不再次重新添加参考。现在它的工作。
只是为了清楚!Beta 程序集被放在 Program Files 下,而旧版本的 System.Web.Mvc 在 GAC 中。
我要自己做这件事。以下是自述文件中的更改列表:
CodePlex Preview 5 和 Beta 之间的更改
- 将默认验证消息更改为对最终用户更友好。
- 将 CompositeViewEngine 重命名为 AutoViewEngine。
- 向 UrlHelper 类型的 Controller 添加了 Url 属性。这使得从控制器内生成基于路由的 URL 变得很方便。
- 添加了 ActionNameSelectorAttribute 抽象基类,作为 ActionNameAttribute 的基类型。通过继承此基本属性类,您可以创建自定义属性,这些属性按名称参与操作选择。
- 向 IViewEngine 添加了一个新的 ReleaseView 方法,该方法允许在视图完成渲染时通知自定义视图引擎。这对于清理或视图池场景很有用。
- 将 ControllerBuilder 方法 DisposeController 重命名为 ReleaseController 以适应为视图引擎建立的模式。
- 删除了 HtmlHelper 类的大部分方法,将它们转换为 HtmlHelper 类的扩展方法。这些方法存在于一个新的命名空间 (System.Web.Mvc.Html) 中。如果您从预览版 5 迁移,则必须将以下元素添加到 Web.config 文件的命名空间部分:
<add namespace="System.Web.Mvc.Html"/>
这使您可以用自己的方法完全替换我们的辅助方法。 - 更改了默认模型绑定器 (DefaultModelBinder) 以处理复杂类型。IModelBinder 接口也已更改为接受 ModelBindingContext 类型的单个参数。
添加了一个新的 HttpVerbs 枚举,其中包含最常用的 HTTP 动词(GET、POST、PUT、DELETE、HEAD)。还向接受枚举的 AcceptVerbsAttribute 添加了构造函数重载。枚举值可以组合。因为可以响应枚举中未包含的 HTTP 谓词,所以 AcceptVerbsAttribute 保留接受字符串数组作为参数的构造函数。例如,以下代码片段显示了一个可以响应 POST 和 PUT 请求的操作方法。
[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Put)] public ActionResult Update() {... }
修改了 RadioButton 辅助方法以确保每个重载都接受一个值。因为单选按钮用于从一组可能的值中指定一个选项,所以为单选按钮指定一个值是必要的。
- 对默认项目模板进行了修改和修复。这包括将脚本文件移动到新的 Scripts 文件夹。默认模板使用 ModelState 类来报告验证错误。
更改了操作方法选择。如果两个操作方法与请求匹配,但其中只有一个具有派生自与请求匹配的 ActionMethodSelectorAttribute 的属性,则调用该操作。在早期版本中,这种情况会导致异常。例如,以下两个动作方法在同一个控制器中:
public ActionResult Edit() { //... } [AcceptVerbs(HttpVerbs.Post)] public ActionResult Edit(FormCollection form) { //... }
在预览版 5 中,对 Edit 操作的 POST 请求会导致异常,因为有两个方法与请求匹配。在 Beta 中,通过 AcceptVerb 属性匹配当前请求的方法具有优先权。在此示例中,第一个方法将处理 Edit 操作的任何非 POST 请求。
- 为接受格式字符串的 ViewDataDictionary.Eval 方法添加了重载。
- 从 ViewContext 类中删除了 ViewName 属性。
- 为值提供者添加了 IValueProvider 接口,以及默认实现 DefaultValueProvider。值提供者提供模型绑定器在绑定到模型对象时使用的值。Controller 类的 UpdateModel 方法已更新,允许您指定自定义值提供程序。
我遇到了和Will一样的问题,不得不和他做类似的事情,包括将 dll 复制到 bin 文件夹。
现在事情在内部 vs.net 服务器中运行,但导致 IIS7 崩溃。
好的,事实证明主要问题之一是我错过了更新 web.config 中的编译程序集的步骤:
<add assembly="System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
我所要做的就是从
%ProgramFiles%\Microsoft ASP.NET\ASP.NET MVC Beta
还可以从codeplex获取最新的 Microsoft.Web.MVC
也更新我的期货程序集。
在 web.config 中添加 2 行
本<assemblies>
节:
<add assembly="System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
这一<namespaces>
节:
<add namespace="System.Web.Mvc.Html"/>
然后我不得不更新<%using (Html.Form())
所有<%using (Html.BeginForm())
在一个代码文件上,我必须添加System.Web.Mvc.Html;
命名空间
我的东西是基于 Rob Conery 的MVC Storefront,所以任何使用它的人都应该能够遵循上述内容。
希望它可以帮助那里的人。
忽略这个...我是个失败者-它是程序文件中的Microsoft ASP.net...不仅仅是ASP.net
也许这应该是第二个问题,但我认为将它们全部放在一个地方可能会有所帮助。
运行 Beta 安装程序时,我的 PC 上没有任何变化。我没有在 Program Files 文件夹中看到该文件夹...没有向 GAC 添加程序集...即使安装程序进入最后一步,然后挂起大约 10 分钟左右。
我现在已经卸载并重新安装了几次,但没有任何运气。
有人有类似的问题吗?
AutoFac 的问题现已在 AutoFac 代码库 http://code.google.com/p/autofac/issues/detail?id=86&can=1的修订版 454 中得到解决
我试图找出新的 ModelBinder 是如何工作的,据我所知它有很大的不同,但我还没有设法找出它是如何工作的..
我的老样子:
public class GuestbookEntryBinder : IModelBinder
{
#region IModelBinder Members
public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState)
{
if (modelType == typeof(GuestbookEntry))
{
return new GuestbookEntry
{
Name = controllerContext.HttpContext.Request.Form["name"] ?? "",
Website = controllerContext.HttpContext.Request.Form["website"] ?? "",
Message = controllerContext.HttpContext.Request.Form["message"] ?? "",
};
}
return null;
}
#endregion
}
新的看起来像:
#region IModelBinder Members
public ModelBinderResult BindModel(ModelBindingContext bindingContext)
{
throw new NotImplementedException();
}
#endregion
有什么提示吗?
我使用 Autofac 作为我的 DI 容器。尝试处置容器对象时会引发空容器异常。
是的,也使用 Autofac 作为 DI 容器。
遇到和这个人一样的问题
http://groups.google.com/group/autofac/browse_thread/thread/68aaf55581392d08
不知道是否可以修复,但在修复之前无法继续......
在一天的大部分时间里都在为此苦苦挣扎之后,我想我会在这里发布我的解决方案。也许这是正常的 Visual Studio 行为,但我以前从未注意到它......
在我现有的项目中,我实际上不得不手动将 Beta 文件移动到 Bin 文件夹。无论出于何种原因,仅使用“添加引用”浏览它是行不通的......
Html.TextBox - 现在的值是对象,而不是字符串。因此,可能存在隐藏错误(不是在编译时,甚至不是在运行时),例如我之前使用过这个重载方法 Html.TextBox(string name, object htmlAttributes)。现在我的属性进入文本框值。
关于 Autofac 问题。autofac讨论组上有一个线程关于需要更新控制器工厂以兼容MVC框架的Beta版本
http://groups.google.com/group/autofac/browse_thread/thread/68aaf55581392d08
我希望他们很快就会发布一个新版本:-)
当我从 Preview 5 升级到 Beta 时,我很难找到 ActionLink 的通用重载。这些似乎不包含在 ASP.NET MVC 的主要版本中,但正在作为“未来”发布。
我找到了必要的程序集(Microsoft.Web.Mvc)@ http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=aspnet&ReleaseId=18459
ViewContext 构造函数中有一个重大更改。它已从:
ViewContext(ControllerContext 上下文,字符串 viewName,ViewDataDictionary viewData,TempDataDictionary tempData)
到:
ViewContext(ControllerContext 上下文,IView 视图,ViewDataDictionary viewData,TempDataDictionary tempData)
这破坏了我的代码,因为我使用的是 MvcContrib.Services.IEmailTemplateService,它在其 RenderMessage 方法中采用 ViewContext。要从模板名称中获取 IView,我正在执行以下操作:
var view = ViewEngines.DefaultEngine.FindView(controllerContext, viewName, null);
不确定这是否是最佳做法,但它似乎有效。
这现在被打破了:
<%=Html.TextBox("Name", new Hash(@class => "required"))%>
在预览版 5 中,上述内容会将 ViewData.Model.Name 的值绑定到文本框。这仍然有效:
<%=Html.TextBox("Name")%>
但是如果要指定html属性,还必须指定值,如下:
<%=Html.TextBox("Name", ViewData.Model.Name, new Hash(@class => "required"))%>
实际上,这并不安全。如果有任何机会 ViewData.Model 可能为空,您需要执行以下操作:
<%=Html.TextBox("Name", ViewData.Model == null ? null : ViewData.Model.Name, new Hash(@class => "required"))%>
此更改似乎与 Beta 版本说明背道而驰:
“...为了减少重载歧义... value 参数已从对象更改为几个辅助方法的字符串。”
TextBox 的 value 参数以前是 string,现在改为 object。因此,为了避免歧义,他们必须删除我最常使用的一个重载。:(
恕我直言,每个 HTML 辅助方法都应该有允许在所有情况下绑定而不指定值的重载。否则,我们最终会得到不一致的视图代码,这会使未来的开发人员感到困惑。
如果您使用期货程序集 (Microsoft.Web.Mvc) 中的 Html.Form,您可能会在 FormMethod 枚举上遇到名称冲突。例如:
Html.Form<FooController>(c => c.Bar(), FormMethod.Post, new Hash(@class => "foobar"))
这将抱怨 FormMethod 是 Microsoft.Web.Mvc 和 System.Web.Mvc 之间的模棱两可的引用。这很可悲,因为恕我直言 BeginForm 没有提供可行的选项,因为它缺少使用 lambda 表达式的覆盖。你唯一的选择是使用魔法字符串,它可以抵抗重构。
似乎最好的解决方案是将以下内容放入使用 FormMethod 的每个视图中:
<%@ Import Namespace="FormMethod=Microsoft.Web.Mvc.FormMethod"%>
啊。希望这是暂时的。我希望期货程序集可以更改为使用 System.Web.Mvc 中的枚举。或者更好的是,希望它们重载 BeginForm 以使用表达式。
似乎 Html.Image 坏了。 从预览版 5 开始,它已移至期货程序集。 我无法想象为什么。无论如何,错误是:
Method not found: 'Void System.Web.Mvc.UrlHelper..ctor(System.Web.Mvc.ViewContext)'
我能看到的最好的解决方案是替换它:
<%=Html.Image("~/Content/Images/logo.jpg") %>
有了这个:
<img src="<%=Html.ResolveUrl("~/Content/Images/logo_350.jpg")%>" />
上面会说什么,除了从 GAC 中删除程序集并重新添加引用之外,我还必须再次运行 Beta 安装程序(这次将正确的程序集放在 GAC 中,尽管我只是使用一个文件参考)。
我怀疑如果我在运行安装程序之前从 GAC 中删除了 Preview 5 程序集(而且我也不知道它们是如何进入那里的),那么一切可能都正常。值得尝试。
万一其他人像我一样愚蠢并在Vista 上工作,您可能不需要为了删除旧程序集而进行上述注册表黑客操作 - 只需从管理员命令提示符运行 gacutil 即可。嗬!
我发现使用空白项目中的名称空间更新 web.config 名称空间元素解决了我的问题。由于接口更改,我还必须更新我的 ModelBinders。