¿Existe (o existirá) una herramienta para convertir el lenguaje de visualización del motor de visualización de WebForm (aspx) a Razor view engine markup (cshtml)?Herramienta para convertir el lenguaje de visualización del motor de WebForm a Razor ver el marcado del motor
Respuesta
Nosotros también enfrentamos el problema de convertir muchas vistas de WebForms a Razor. Y adivina qué, también hemos llegado con una herramienta:
https://github.com/telerik/razor-converter
También se basa en expresiones regulares (y un buen número de ellos) para dar sentido a la WebForms galimatías, al igual que la herramienta por JohnnyO. La nuestra podría cubrir algunos casos más, pero no confíe en mi palabra y pruébelo en algunas vistas.
Aquí hay una aplicación de consola simple que escribí para convertir vistas de WebForms a Razor. Lamentablemente, no es a prueba de balas. He convertido aproximadamente 20 vistas con esto, y estoy descubriendo que para vistas simples, lo hace 100% correcto, pero cuando la vista se vuelve realmente complicada, la conversión es solo aproximadamente 80% correcta. Incluso al 80%, es mejor que tener que empezar desde el principio a mano.
Hay algunas cosas en esta herramienta de conversión que pueden ser específicas de cómo diseñé mis vistas de WebForms, así que lo comenté para que pueda eliminarlo o personalizarlo.
Puede usarlo ejecutando la aplicación de consola y pasando una ruta de carpeta o de archivo. Si pasa una carpeta, convertirá todos los archivos .aspx y .ascx en la carpeta (pero no volverá a aparecer en las subcarpetas). Si pasa en una ruta de archivo, solo convertirá ese archivo. Una vez hecho esto con la conversión, creará un nuevo archivo .cshtml con el mismo nombre que el archivo .aspx o .ascx.
ADVERTENCIA: si ya tiene un archivo .cshtml con el mismo nombre que el archivo .aspx/.ascx que está intentando convertir, esta aplicación sobrescribirá el archivo .cshtml cuando complete el archivo .aspx /. conversión de ascx
UTILÍCELO BAJO SU PROPIO RIESGO. ASEGÚRESE DE RESPALDAR TODO ANTES DE UTILIZAR ESTA HERRAMIENTA.
Nota: si su archivo aspx/ascx está marcado como "solo lectura", obtendrá un error porque la aplicación de la consola no podrá abrirlo. Asegúrese de que el indicador de solo lectura esté desactivado en todos los archivos aspx/ascx que intente convertir.
class Program {
private readonly static string razorExtension = ".cshtml";
/// <summary>Usage: RazorConverter.exe "C:\Files" or RazorConverter.exe "C:\Files\MyFile.aspx"</summary>
static void Main(string[] args) {
if (args.Length < 1)
throw new ArgumentException("File or folder path is missing.");
string path = args[0];
List<string> convertedFiles = new List<string>();
Regex webFormsExtension = new Regex(".aspx$|.ascx$");
if (Directory.Exists(path)) {
foreach (var file in Directory.GetFiles(path, "*.aspx")) {
var outputFile = webFormsExtension.Replace(file, razorExtension);
ConvertToRazor(file, outputFile);
convertedFiles.Add(file);
}
foreach (var file in Directory.GetFiles(path, "*.ascx")) {
var outputFile = webFormsExtension.Replace(file, razorExtension);
ConvertToRazor(file, outputFile);
convertedFiles.Add(file);
}
} else if (File.Exists(path)) {
var match = webFormsExtension.Match(path);
if (match.Success) {
ConvertToRazor(path, webFormsExtension.Replace(path, razorExtension));
convertedFiles.Add(path);
} else {
throw new ArgumentException(String.Format("{0} file isn't a WebForms view", path));
}
} else {
throw new ArgumentException(String.Format("{0} doesn't exist", path));
}
Console.WriteLine(String.Format("The following {0} files were converted:", convertedFiles.Count));
foreach (var file in convertedFiles) {
Console.WriteLine(file);
}
}
private static void ConvertToRazor(string inputFile, string outputFile) {
// Known Bug: when writing anything directly to the response (other than for HTML helpers (e.g. Html.RenderPartial or Html.RenderAction)),
// this Converter will not correctly generate the markup. For example:
// <% Html.RenderPartial("LogOnUserControl"); %> will properly convert to @{ Html.RenderPartial("LogOnUserControl"); }
// but
// <% MyCustom("Foo"); %> will incorrectly convert to @MyCustom("Foo");
string view;
using (FileStream fs = new FileStream(inputFile, FileMode.Open))
using (StreamReader sr = new StreamReader(fs)) {
view = sr.ReadToEnd();
}
// Convert Comments
Regex commentBegin = new Regex("<%--\\s*");
Regex commentEnd = new Regex("\\s*--%>");
view = commentBegin.Replace(view, "@*");
view = commentEnd.Replace(view, "*@");
// Convert Model
Regex model = new Regex("(?<=Inherits=\"System.Web.Mvc.ViewPage<|Inherits=\"System.Web.Mvc.ViewUserControl<)(.*?)(?=>\")");
Regex pageDeclaration = new Regex("(<%@ Page|<%@ Control).*?%>");
Match modelMatch = model.Match(view);
if (modelMatch.Success) {
view = pageDeclaration.Replace(view, "@model " + modelMatch.Value);
} else {
view = pageDeclaration.Replace(view, String.Empty);
}
// TitleContent
// I'm converting the "TitleContent" ContentPlaceHolder to View.Title because
// that's what TitleContent was for. You may want to ommit this.
Regex titleContent = new Regex("<asp:Content.*?ContentPlaceHolderID=\"TitleContent\"[\\w\\W]*?</asp:Content>");
Regex title = new Regex("(?<=<%:\\s).*?(?=\\s*%>)");
var titleContentMatch = titleContent.Match(view);
if (titleContentMatch.Success) {
var titleVariable = title.Match(titleContentMatch.Value).Value;
view = titleContent.Replace(view, "@{" + Environment.NewLine + " View.Title = " + titleVariable + ";" + Environment.NewLine + "}");
// find all references to the titleVariable and replace it with View.Title
Regex titleReferences = new Regex("<%:\\s*" + titleVariable + "\\s*%>");
view = titleReferences.Replace(view, "@View.Title");
}
// MainContent
// I want the MainContent ContentPlaceholder to be rendered in @RenderBody().
// If you want another section to be rendered in @RenderBody(), you'll want to modify this
Regex mainContent = new Regex("<asp:Content.*?ContentPlaceHolderID=\"MainContent\"[\\w\\W]*?</asp:Content>");
Regex mainContentBegin = new Regex("<asp:Content.*?ContentPlaceHolderID=\"MainContent\".*?\">");
Regex mainContentEnd = new Regex("</asp:Content>");
var mainContentMatch = mainContent.Match(view);
if (mainContentMatch.Success) {
view = view.Replace(mainContentMatch.Value, mainContentBegin.Replace(mainContentEnd.Replace(mainContentMatch.Value, String.Empty), String.Empty));
}
// Match <%= Foo %> (i.e. make sure we're not HTML encoding these)
Regex replaceWithMvcHtmlString = new Regex("<%=\\s.*?\\s*%>"); // removed * from the first <%=\\s.*?\\s*%> here because I couldn't figure out how to do the equivalent in the positive lookbehind in mvcHtmlStringVariable
Regex mvcHtmlStringVariable = new Regex("(?<=<%=\\s).*?(?=\\s*%>)");
// Match <%, <%:
Regex replaceWithAt = new Regex("<%:*\\s*");
// Match %>, <% (but only if there's a proceeding })
Regex replaceWithEmpty = new Regex("\\s*%>|<%\\s*(?=})");
var replaceWithMvcHtmlStrings = replaceWithMvcHtmlString.Matches(view);
foreach (Match mvcString in replaceWithMvcHtmlStrings) {
view = view.Replace(mvcString.Value, "@MvcHtmlString.Create(" + mvcHtmlStringVariable.Match(mvcString.Value).Value + ")");
}
view = replaceWithEmpty.Replace(view, String.Empty);
view = replaceWithAt.Replace(view, "@");
Regex contentPlaceholderBegin = new Regex("<asp:Content[\\w\\W]*?>");
Regex contentPlaceholderId = new Regex("(?<=ContentPlaceHolderID=\").*?(?=\")");
Regex contentPlaceholderEnd = new Regex("</asp:Content>");
MatchCollection contentPlaceholders = contentPlaceholderBegin.Matches(view);
foreach (Match cp in contentPlaceholders) {
view = view.Replace(cp.Value, "@section " + contentPlaceholderId.Match(cp.Value).Value + " {");
}
view = contentPlaceholderEnd.Replace(view, "}");
// if we have something like @Html.RenderPartial("LogOnUserControl");, replace it with @{ Html.RenderPartial("LogOnUserControl"); }
Regex render = new Regex("@Html\\.\\S*\\(.*\\)\\S*?;");
var renderMatches = render.Matches(view);
foreach (Match r in renderMatches) {
view = view.Replace(r.Value, "@{ " + r.Value.Substring(1) + " }");
}
using (FileStream fs = new FileStream(outputFile, FileMode.Create)) {
byte[] bytes = Encoding.UTF8.GetBytes(view);
fs.Write(bytes, 0, bytes.Length);
}
}
}
Los usuarios de ReSharper pueden votar por una característica para convertir automáticamente de aspx a cshtml. ReSharper tendrá una representación AST para ambos lados, por lo que podrían (en teoría) hacer un trabajo muy sólido sin requerir expresiones regulares.
- 1. Variables globales en el motor Razor View
- 2. Motor ASP.NET MVC Razor view
- 3. Uso del motor Razor en cadenas - no vistas
- 4. Rails.root del motor
- 5. Rails Configuración del motor
- 6. instalando el motor razor view para Visual Studio
- 7. ¿Funciona el motor Razor View Engine para Mono?
- 8. Salida de Json con el motor de vista Razor
- 9. ¿Es posible usar el motor Razor 2.0 view en mono?
- 10. Cómo reemplazar el motor de JavaScript del navegador con LLVM?
- 11. Seguridad del subproceso del motor Matlab API
- 12. ¿Cuál es el motor de búsqueda del navegador Sogou?
- 13. HL7 Interfaz Recomendaciones del motor
- 14. ¿Pueden funcionar juntos el motor Razor y ember.js?
- 15. Rutas del motor en el Controlador de aplicación
- 16. ¿Cómo funciona el sandbox del motor de la aplicación Google?
- 17. Algoritmo del motor de recomendación básica
- 18. usando la variable javascript en el motor MVC3 Razor view
- 19. ¿Cómo habilitar el enlace de datos en KnockoutJS usando el Motor de visualización "Razor" ASP.NET MVC 3?
- 20. Una forma de agregar before_filter del motor a la aplicación
- 21. Dilema del motor de almacenamiento MySQL
- 22. ¿Cuál es el propósito del motor BLACKHOLE de MySQL?
- 23. Herramienta para probar el marcado de Schema.org
- 24. ¿Voces del motor de texto a voz de Google?
- 25. Diagrama de flujo del analizador del motor de búsqueda
- 26. Optimización del motor de búsqueda - ¿Guía del desarrollador?
- 27. AjaxForm y aplicación del motor Blobstore
- 28. ¿Por qué Eclipse considera que el jar de sdk del motor de aplicaciones es el directorio donde está el SDK del motor de aplicaciones?
- 29. Android: "no se puede inicializar el motor del visualizador"
- 30. diferencia entre el motor de diseño y el motor de JavaScript
Esto funcionó bien para mí. ¡Gracias por compartir! –
Gracias por esta útil herramienta. Un problema que encontré fue que los comentarios de mi servidor se eliminaron durante la conversión. Sería bueno tenerlos convertidos a la sintaxis '@ * ... * @'. –
Indeed :) Arreglaremos esto –