asp.net-mvc 如何将现有的 asp.net 应用程序迁移到 asp.net MVC 模式格式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/532227/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to migrate existing asp.net application to asp.net MVC pattern format
提问by Nissan
I want to migrate an existing ASP.NET application to an ASP.NET MVC pattern format. What procedure should I follow? Any step-by-step instructions would be very helpful.
我想将现有的 ASP.NET 应用程序迁移到 ASP.NET MVC 模式格式。我应该遵循什么程序?任何分步说明都会非常有帮助。
回答by Nissan
These is my step-by-step guide, based on steps we have taken at my company during our move from a classic ASP.Net Webforms to ASP.Net MVC. It's not perfect, and still ongoing since we have to do this in stages because of the size of the site, but perhaps someone else will find and file an improved answer based on our results.
这些是我的分步指南,基于我们在从经典的 ASP.Net Webforms 迁移到 ASP.Net MVC 期间在我公司采取的步骤。它并不完美,并且仍在进行中,因为由于站点的大小,我们必须分阶段执行此操作,但也许其他人会根据我们的结果找到并提交改进的答案。
Stages: 1. Planning - moving to MVC from Web Forms in ASP.Net requires some careful planning. The mistake we made in our move is not realising that there are are really two aspects to this stage of planning, route planning and model/controller/action planning. Not doing this will cause serious issues later on as you try to extend functionality of your site or hit more complex migrations.
阶段: 1. 计划 - 从 ASP.Net 中的 Web 窗体迁移到 MVC 需要一些仔细的计划。我们在行动中犯的错误是没有意识到这个阶段的规划实际上有两个方面,路线规划和模型/控制器/动作规划。当您尝试扩展站点的功能或进行更复杂的迁移时,不这样做会在以后导致严重的问题。
Tips: - Look at your current sitemap, and design the improved sitemap/directory structure to be used in the ASP.Net MVC application. Figure out a 'language' for your website, e.g. the default behaviour of ASP.Net MVC is to have a http://sitename/{controller}/{action}/{id} behavior, but you can override this as you gain more experience hacking routing rules.
提示: - 查看您当前的站点地图,并设计要在 ASP.Net MVC 应用程序中使用的改进的站点地图/目录结构。为您的网站找出一种“语言”,例如 ASP.Net MVC 的默认行为是具有http://sitename/{controller}/{action}/{id} 行为,但您可以在获得时覆盖它更多的黑客路由规则经验。
Remember by default each Controller will be routed to via a virtual subdirectory of your application, e.g. http://sitename/Xwould route to XController (and by default its Index method), http://sitename/Y/Getwould route to YController's Get() method. You can change this as you please (routing's really powerful), but that's beyond the scope of this answer.
Using the existing sitemap, specify what folder in the MVC structure each current .aspx page should fall (of course, first ask if it should exist at all).
If Scripts, Images etc are not stored together, or in some 'reserved name' folders within each subdirectory, consider doing so now as you're redesigning. This is as it would greatly simplify your design by allowing you to use a Map.IgnoreRoute() routing rule command in the Global.aspx.cs file to bypass processing these folders as routes.
请记住,默认情况下,每个 Controller 将通过应用程序的虚拟子目录路由到,例如http://sitename/X将路由到 XController(默认情况下它的 Index 方法),http://sitename/Y/Get将路由到YController 的 Get() 方法。您可以随意更改它(路由非常强大),但这超出了本答案的范围。
使用现有的站点地图,指定每个当前 .aspx 页面应位于 MVC 结构中的哪个文件夹(当然,首先询问它是否应该存在)。
如果脚本、图像等未存储在一起,或未存储在每个子目录中的某些“保留名称”文件夹中,请考虑在重新设计时立即执行此操作。这是因为它允许您使用 Global.aspx.cs 文件中的 Map.IgnoreRoute() 路由规则命令来绕过将这些文件夹作为路由处理,从而大大简化您的设计。
In our case we mirrored the real subdirectory layout of the current site, where each subdirectory became a controller, e.g. /Account would have an AccountController, /X would have XController. All pages that fell inside there were replaced by actions within each Controller. e.g. http://sitename/profile/about.aspxnow became http://sitename/profile/aboutand mapped to the "about" ActionResult method inside the profileController. This is allowing us to stay agile by doing a partial migration of one or two directories (or several files inside one directory) over a series of sprints, rather than having to migrate the entire site in one go over a much longer duration.
在我们的例子中,我们镜像了当前站点的真实子目录布局,其中每个子目录成为一个控制器,例如 /Account 将有一个 AccountController,/X 将有 XController。里面的所有页面都被每个控制器中的动作替换。例如http://sitename/profile/about.aspx现在变成了http://sitename/profile/about并映射到 profileController 中的“about”ActionResult 方法。这使我们能够通过在一系列冲刺中对一个或两个目录(或一个目录中的多个文件)进行部分迁移来保持敏捷,而不必在更长的时间内一次性迁移整个站点。
Create a new ASP.Net MVC application in Visual Studio and immediately create the rules in the Global.asax file that ignore routing rules for the folders that exist in the current site.
Copy the folders from the ASP.Net Web Application to the ASP.Net MVC Application folders. Run the website and ensure it works properly (it should as no routing rules are being used yet).
Pick a subdirectory or subset of files within a subdirectory to migrate.
For each .aspx page inside this subdirectory:
a. Create its View first. I tend to use the web-browser rendered version of the page as my base HTML, and then put placeholders in the locations that I know are filled with dynamic data.
b. Using the placeholders for the dynamic data, create a first-draft of the Model using simple data types. This model will start off simple, but be constantly refactored as you migrate more pages from the original site, so don't worry if it starts looking a little heavy. If you find yourself with too many Properties in one Model for your taste, or see a logical grouping beyond just the Model of certain subset of items, perhaps this is a sign the Model needs to be refactored to have an object instead with these simple data types as properties but is composed in the business logic layer.
c. Create the controller if it hasnt been created yet, and put the appropriate ActionResult method for the Action your planning has determined should route to this view. If you realise something that there is a new action that doesn't map to a page from the old site, then create the View for the controller, and include appropriate //TODO: tags so you can keep track of this to implement after you have migrated the existing pages.
d. Consider putting in some handling code for unknown actions as well, if you don't have a {*catchall} Routing rule for this already in your global.asax.cs file.
e. Create the constructor classes for the Model so that given certain parameters that the Controller will have (passed in as your {id} or possibly a Request.QueryString parameter from the URL, or an HTTP header or cookie), the Model will know how to reach out to your existing business logic classes and build up itself for rendering by the View.
f. Go to next page in the list and start again from step a.
Finally create the routing rule that will call your new Controller and allow the Actions you have written to be implemented. Debug, debug, debug...Once you're happy all is well, remove the existing folder and files you've migrated from your main site, as well as the IgnoreRoute rule in the global.asax.cs.
Create a redirect in whatever manner you prefer if you wish to preserve old directory and file names for continuity (e.g. users may have bookmarked certain pages in the old site already).
在 Visual Studio 中创建一个新的 ASP.Net MVC 应用程序,并立即在 Global.asax 文件中创建忽略当前站点中存在的文件夹的路由规则的规则。
将文件夹从 ASP.Net Web 应用程序复制到 ASP.Net MVC 应用程序文件夹。运行网站并确保其正常运行(应该是因为尚未使用路由规则)。
选择要迁移的子目录或子目录中的文件子集。
对于此子目录中的每个 .aspx 页面:
一种。首先创建它的视图。我倾向于使用 Web 浏览器呈现的页面版本作为我的基本 HTML,然后在我知道充满动态数据的位置放置占位符。
湾 使用动态数据的占位符,使用简单的数据类型创建模型的初稿。这个模型一开始很简单,但随着您从原始站点迁移更多页面,它会不断重构,所以如果它看起来有点沉重,请不要担心。如果您发现自己在一个 Model 中有太多的属性,或者看到超出某些项目子集的 Model 之外的逻辑分组,这可能表明 Model 需要重构以拥有一个对象而不是这些简单的数据类型作为属性,但在业务逻辑层中组合。
C。如果尚未创建控制器,则创建控制器,并为您的计划确定应该路由到此视图的操作放置适当的 ActionResult 方法。如果你意识到有一个新动作没有映射到旧站点的页面,那么为控制器创建视图,并包含适当的 //TODO: 标签,以便你可以跟踪这个以在你之后实现已迁移现有页面。
d. 如果您的 global.asax.cs 文件中没有 {*catchall} 路由规则,也可以考虑为未知操作添加一些处理代码。
e. 为模型创建构造函数类,以便给定控制器将具有的某些参数(作为您的 {id} 或可能来自 URL 的 Request.QueryString 参数,或 HTTP 标头或 cookie 传入),模型将知道如何接触您现有的业务逻辑类并构建自身以供视图呈现。
F。转到列表中的下一页并从步骤 a 重新开始。
最后创建路由规则,该规则将调用您的新控制器并允许实现您编写的操作。调试、调试、调试...一旦您感到满意,请删除您从主站点迁移的现有文件夹和文件,以及 global.asax.cs 中的 IgnoreRoute 规则。
如果您希望保留旧的目录和文件名以保持连续性(例如,用户可能已经在旧站点中为某些页面添加了书签),则以您喜欢的任何方式创建重定向。
Note: If you are keeping the exact names of the old subdirectories in your MVC site during the porting phase, it's preferable to migrate a whole subdirectory at a time I've realised, because by only doing a few files the routing rules you need to write become more complex since if an existing folder exists with the same name as a routing rule's path and that folder has a Default.aspx file then (/foldername/) will default to the Default.aspx page, as it takes precidence over the routing rules.
注意:如果您在移植阶段保留 MVC 站点中旧子目录的确切名称,最好在我意识到的时候迁移整个子目录,因为只需执行几个文件,您需要路由规则写入变得更加复杂,因为如果存在与路由规则路径同名的现有文件夹,并且该文件夹具有 Default.aspx 文件,则 (/foldername/) 将默认为 Default.aspx 页,因为它优先于路由规则。
Tip: Seriously consider using a tool like RouteDebugfor route debugging so you can figure out strange things like above, or when you have multiple routing rules firing and causing unexpected behaviors.
提示:认真考虑使用RouteDebug 之类的工具进行路由调试,这样您就可以找出上述奇怪的事情,或者当您有多个路由规则触发并导致意外行为时。
This is my first draft, please give me feedback if I've missed any steps or if you see any holes in the guide, and I'll modify the answer appropriately.
这是我的初稿,如果我遗漏了任何步骤或者您在指南中看到任何漏洞,请给我反馈,我会适当地修改答案。
回答by Tomas Aschan
I don't think there is such a thing as a "step-by-step migration" from ASP.NET WebForms to ASP.NET MVC. They are two completely different design patterns built on the same framework, but there are (in most cases) a lot of things that need not only to be moved, but completely re-designed, if you don't just want to build a web app on the MVC template project instead of the WebForms template.
我不认为存在从 ASP.NET WebForms 到 ASP.NET MVC 的“逐步迁移”这样的事情。它们是建立在同一个框架上的两种完全不同的设计模式,但是(在大多数情况下)有很多东西不仅需要移动,还需要完全重新设计,如果您不只是想构建一个网络app 上的 MVC 模板项目而不是 WebForms 模板。
The main reason for this is the separation of concerns, which is much stricter in MVC than in WebForms. I am currently working (well, I should be...) on migrating an old and pretty buggy hobby-project from WebForms to MVC and my approach has basically been "look at the functionality, re-build it from scratch." Of course I had some helper methods for formatting output etc that I just included in my new project, but most of the basic stuff I chose just to redo completely. You'd be surprised how little it takes me to reach the same goals with MVC now, that I set up for the WebForms app a year-and-a-half ago - with the use of Entity Framework, jQuery and other sweet stuff, you'll be able to produce results within a couple of hours.
造成这种情况的主要原因是关注点分离,这在 MVC 中比在 WebForms 中严格得多。我目前正在(嗯,我应该……)将一个旧的、有缺陷的业余爱好项目从 WebForms 迁移到 MVC,我的方法基本上是“查看功能,从头开始重新构建它”。当然,我有一些用于格式化输出等的辅助方法,我刚刚包含在我的新项目中,但我选择的大部分基本内容只是完全重做。你会惊讶我现在用 MVC 达到相同的目标是多么的少,我在一年半前为 WebForms 应用程序设置 - 使用实体框架、jQuery 和其他甜蜜的东西,您将能够在几个小时内产生结果。
回答by Iman
May these few additional tips will assist
可能这些额外的提示会有所帮助
- Replace <%-- comment tags with @*
use @RenderSection("Footer",false) for @section footer { } and so on,if you have any additional ContentPlaceHolderexcept the main body in View which RenderBody() .
all the old normal runat="server"tags are harmless and do not prevent compile and can be cleaned afterwards
all controls Visibility which was easily controlled in code behind and markup (Visible="True") and controlled in code_behindby use of Control Id must be refactored to ViewBagCollection and @ifblocks in Razor view.
you can also watch this excellent course of Pluralsight around this topic (3h 49m)
- 用@* 替换 <%-- 注释标签
使用@RenderSection("Footer",false) for @section footer { } 等等,如果你有任何额外的ContentPlaceHolder除了 View 中的RenderBody()主体。
所有旧的正常runat="server"标签都是无害的,不会阻止编译,之后可以清理
所有在代码隐藏和标记 (Visible="True") 中易于控制并在code_behind 中使用 Control Id控制的控件可见性必须重构为ViewBagCollection 和Razor 视图中的@if块。
您还可以观看围绕该主题的 Pluralsight 优秀课程(3 小时 49 米)
回答by Morph
My answer would be "You don't" :). If you really want to do this, you can use the current asp.net site as your end goal, or as a requirements 'document'. And maybe you can use the datalayer in your model, but you'll have to redesign the whole site.
我的回答是“你不会”:)。如果您真的想这样做,您可以使用当前的 asp.net 站点作为您的最终目标,或作为需求“文档”。也许您可以在模型中使用数据层,但您必须重新设计整个站点。
As Tomas already pointed out, it's VERY different from classic asp.net.
正如 Tomas 已经指出的那样,它与经典的 asp.net 非常不同。

