2010-10-16 18 views
27

करता है करने के लिए वेबफ़ॉर्म दृश्य इंजन मार्कअप कन्वर्ट करने के लिए (या होगा) एक उपकरण उस्तरा दृश्य इंजन मार्कअप (cshtml) को वेबफ़ॉर्म दृश्य इंजन मार्कअप (aspx) कन्वर्ट करने के लिए मौजूद हैं?उपकरण उस्तरा दृश्य इंजन मार्कअप

उत्तर

36

हमें भी बहुत सारे वेबफॉर्म दृश्यों को रेजर में परिवर्तित करने की समस्या का सामना करना पड़ा। और लगता है क्या, हम भी एक उपकरण के साथ आया है:

https://github.com/telerik/razor-converter

यह भी regexes (और काफी एक उनमें से कुछ) WebForms mumbo- जंबो की समझ बनाने के लिए पर निर्भर करता है, बहुत उपकरण की तरह जॉनीओ द्वारा हमारा कुछ और मामलों को कवर कर सकता है, लेकिन इसके लिए मेरा शब्द न लें और इसके बजाय कुछ विचारों पर आज़माएं।

+1

यह मेरे लिए अच्छा काम करता है। साझा करने के लिए धन्यवाद! –

+0

इस उपयोगी उपकरण के लिए धन्यवाद। मुझे मिला एक मुद्दा यह था कि रूपांतरण के दौरान मेरी सर्वर टिप्पणियां हटा दी गई थीं। उन्हें '@ * ... * @ वाक्यविन्यास में परिवर्तित करना अच्छा लगेगा। –

+0

दरअसल :) हम इस –

10

यहाँ एक सरल कंसोल अनुप्रयोग है कि मैं रेजर को WebForms विचारों कन्वर्ट करने के लिए लिखा था है। दुर्भाग्यवश, यह बुलेट प्रमाण नहीं है। मैंने इसके साथ लगभग 20 विचारों को परिवर्तित कर दिया है, और मुझे लगता है कि साधारण विचारों के लिए, यह 100% सही हो जाता है, लेकिन जब दृश्य वास्तव में जटिल हो जाता है, तो रूपांतरण केवल 80% सही होता है। 80% पर भी, शुरुआत से ही शुरुआत से शुरू करना बेहतर है।

इस रूपांतरण उपकरण है कि कैसे मैं अपने WebForms विचारों डिज़ाइन किया गया के लिए विशिष्ट हो सकता है में कुछ बातें कर रहे हैं, तो मैं यह टिप्पणी की ताकि आप इसे निकाल सकते हैं या अनुकूलित कर सकते हैं।

आप कंसोल अनुप्रयोग को क्रियान्वित करने और एक फ़ोल्डर पथ या फ़ाइल पथ में पास करके इसका इस्तेमाल कर सकते हैं। यदि आप किसी फ़ोल्डर में पास करते हैं, तो यह फ़ोल्डर में सभी .aspx और .ascx फ़ाइलों को परिवर्तित करेगा (लेकिन यह सब-फ़ोल्डर्स में पुन: स्थापित नहीं होगा)। यदि आप फ़ाइल पथ में पास करते हैं, तो यह केवल उस फ़ाइल को कन्वर्ट करेगा। एक बार यह रूपांतरण के साथ किया जाता है, यह एक नई .cshtml फ़ाइल को उसी नाम के साथ .aspx या .ascx फ़ाइल के रूप में बनाएगा।

चेतावनी: यदि आपके पास पहले से ही .cxtml फ़ाइल है जो .aspx/.ascx फ़ाइल के समान नाम के साथ है जिसे आप कनवर्ट करने का प्रयास कर रहे हैं, तो यह ऐप .cxtml फ़ाइल को ओवरराइट करेगा जब यह .aspx/को पूरा करेगा। एसीएक्स रूपांतरण।

अपने जोखिम पर उपयोग करें। इस उपकरण का उपयोग करने से पहले सबकुछ वापस लेने के लिए सुनिश्चित करें।

नोट: यदि आपके aspx/ascx फ़ाइल के रूप में चिह्नित किया गया है "केवल पढ़ने", आप एक त्रुटि प्राप्त होगी क्योंकि सांत्वना एप्लिकेशन को खोलने के लिए सक्षम नहीं होगा। सुनिश्चित करें कि केवल एएसपीएक्स/एसीएक्स फाइलों पर पढ़ने के लिए ध्वज बंद कर दिया गया है जिसे आप कन्वर्ट करने का प्रयास कर रहे हैं।

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); 
     } 
    } 
} 
2

ReSharper के उपयोगकर्ताओं को एक सुविधा स्वचालित रूप से aspx से कन्वर्ट करने के लिए cshtml करने के लिए वोट करने के लिए पसंद कर सकते हैं। ReSharper दोनों पक्षों के लिए एक एएसटी प्रतिनिधित्व होगा, इसलिए वे (सिद्धांत में) regexs की आवश्यकता के बिना इसके एक बहुत मजबूत काम कर सकते हैं।

http://youtrack.jetbrains.net/issue/RSRP-194060

संबंधित मुद्दे