Fixes: #U4-1472 - XmlHelper.

Fixes: #U4-1488 - partial view macro engine issues.
This commit is contained in:
Shannon Deminick
2013-01-19 06:38:02 +03:00
parent e1902a54f0
commit 3e28376ae7
6 changed files with 78 additions and 26 deletions

View File

@@ -20,7 +20,7 @@ namespace Umbraco.Core
/// <param name="text">The text.</param>
/// <param name="xmlDoc">The XML doc.</param>
/// <returns></returns>
internal static XmlNode ImportXmlNodeFromText(string text, ref XmlDocument xmlDoc)
public static XmlNode ImportXmlNodeFromText(string text, ref XmlDocument xmlDoc)
{
xmlDoc.LoadXml(text);
return xmlDoc.FirstChild;
@@ -80,7 +80,7 @@ namespace Umbraco.Core
/// <param name="name">The node name.</param>
/// <param name="value">The node value.</param>
/// <returns>A XmlNode</returns>
public static XmlNode AddCDataNode(XmlDocument xd, string name, string value)
public static XmlNode AddCDataNode(XmlDocument xd, string name, string value)
{
var temp = xd.CreateNode(XmlNodeType.Element, name, "");
temp.AppendChild(xd.CreateCDataSection(value));
@@ -92,7 +92,7 @@ namespace Umbraco.Core
/// </summary>
/// <param name="n">The XmlNode.</param>
/// <returns>the value as a string</returns>
internal static string GetNodeValue(XmlNode n)
public static string GetNodeValue(XmlNode n)
{
var value = string.Empty;
if (n == null || n.FirstChild == null)
@@ -108,7 +108,7 @@ namespace Umbraco.Core
/// <returns>
/// <c>true</c> if the specified string appears to be XML; otherwise, <c>false</c>.
/// </returns>
internal static bool CouldItBeXml(string xml)
public static bool CouldItBeXml(string xml)
{
if (!string.IsNullOrEmpty(xml))
{
@@ -131,7 +131,7 @@ namespace Umbraco.Core
/// <param name="rootName">Name of the root.</param>
/// <param name="elementName">Name of the element.</param>
/// <returns>Returns an <c>System.Xml.XmlDocument</c> representation of the delimited string data.</returns>
internal static XmlDocument Split(string data, string[] separator, string rootName, string elementName)
public static XmlDocument Split(string data, string[] separator, string rootName, string elementName)
{
return Split(new XmlDocument(), data, separator, rootName, elementName);
}
@@ -145,7 +145,7 @@ namespace Umbraco.Core
/// <param name="rootName">Name of the root node.</param>
/// <param name="elementName">Name of the element node.</param>
/// <returns>Returns an <c>System.Xml.XmlDocument</c> representation of the delimited string data.</returns>
internal static XmlDocument Split(XmlDocument xml, string data, string[] separator, string rootName, string elementName)
public static XmlDocument Split(XmlDocument xml, string data, string[] separator, string rootName, string elementName)
{
// load new XML document.
xml.LoadXml(string.Concat("<", rootName, "/>"));
@@ -174,7 +174,7 @@ namespace Umbraco.Core
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
internal static Dictionary<string, string> GetAttributesFromElement(string tag)
public static Dictionary<string, string> GetAttributesFromElement(string tag)
{
var m =
Regex.Matches(tag, "(?<attributeName>\\S*)=\"(?<attributeValue>[^\"]*)\"",

View File

@@ -13,6 +13,7 @@ using umbraco.cms.businesslogic.macro;
using umbraco.interfaces;
using Umbraco.Web.Mvc;
using Umbraco.Core;
using System.Web.Mvc.Html;
namespace Umbraco.Web.Macros
{
@@ -65,8 +66,7 @@ namespace Umbraco.Web.Macros
// we rewrite how macro engines work.
public IEnumerable<string> SupportedExtensions
{
get { return Enumerable.Empty<string>(); }
//get { return new[] {"cshtml", "vbhtml"}; }
get { return Enumerable.Empty<string>(); }
}
//NOTE: We do not return any supported extensions because we don't want the MacroEngineFactory to return this
@@ -76,7 +76,6 @@ namespace Umbraco.Web.Macros
public IEnumerable<string> SupportedUIExtensions
{
get { return Enumerable.Empty<string>(); }
//get { return new[] { "cshtml", "vbhtml" }; }
}
public Dictionary<string, IMacroGuiRendering> SupportedProperties
{
@@ -118,26 +117,32 @@ namespace Umbraco.Web.Macros
routeVals.Values.Add("action", "Index");
routeVals.DataTokens.Add("umbraco-context", umbCtx); //required for UmbracoViewPage
////lets render this controller as a child action if we are currently executing using MVC
////(otherwise don't do this since we're using webforms)
//var mvcHandler = http.CurrentHandler as MvcHandler;
//if (mvcHandler != null)
//{
// routeVals.DataTokens.Add("ParentActionViewContext",
// //If we could get access to the currently executing controller we could do this but this is nearly
// //impossible. The only way to do that would be to store the controller instance in the route values
// //in the base class of the UmbracoController.... but not sure the reprocussions of that, i think it could
// //work but is a bit nasty.
// new ViewContext());
//}
//lets render this controller as a child action if we are currently executing using MVC
//(otherwise don't do this since we're using webforms)
var mvcHandler = http.CurrentHandler as MvcHandler;
var viewContext = new ViewContext {ViewData = new ViewDataDictionary()};;
if (mvcHandler != null)
{
//try and extract the current view context from the route values, this would be set in the UmbracoViewPage.
if (mvcHandler.RequestContext.RouteData.DataTokens.ContainsKey(Constants.DataTokenCurrentViewContext))
{
viewContext = (ViewContext) mvcHandler.RequestContext.RouteData.DataTokens[Constants.DataTokenCurrentViewContext];
}
routeVals.DataTokens.Add("ParentActionViewContext", viewContext);
}
var request = new RequestContext(http, routeVals);
string output;
using (var controller = new PartialViewMacroController(umbCtx, macro, currentPage))
{
controller.ControllerContext = new ControllerContext(request, controller);
//bubble up the model state from the main view context to our custom controller.
//when merging we'll create a new dictionary, otherwise you might run into an enumeration error
// caused from ModelStateDictionary
controller.ModelState.Merge(new ModelStateDictionary(viewContext.ViewData.ModelState));
controller.ControllerContext = new ControllerContext(request, controller);
//call the action to render
var result = controller.Index();
output = controller.RenderViewResultAsString(result);
output = controller.RenderViewResultAsString(result);
}
return output;
@@ -163,5 +168,7 @@ namespace Umbraco.Web.Macros
throw new InvalidCastException("All Partial View Macro views must inherit from " + typeof(PartialViewMacroPage).FullName);
return webPage;
}
}
}

View File

@@ -1,7 +1,12 @@
namespace Umbraco.Web.Mvc
{
/// <summary>
/// constants
/// </summary>
internal static class Constants
{
public const string ViewLocation = "~/Views";
internal const string ViewLocation = "~/Views";
internal const string DataTokenCurrentViewContext = "umbraco-current-view-context";
}
}

View File

@@ -108,7 +108,9 @@ namespace Umbraco.Web.Mvc
/// <param name="controller"></param>
internal static void EnsureViewObjectDataOnResult(this ControllerBase controller, ViewResultBase result)
{
result.ViewData.ModelState.Merge(controller.ViewData.ModelState);
//when merging we'll create a new dictionary, otherwise you might run into an enumeration error
// caused from ModelStateDictionary
result.ViewData.ModelState.Merge(new ModelStateDictionary(controller.ViewData.ModelState));
// Temporarily copy the dictionary to avoid enumerator-modification errors
var newViewDataDict = new ViewDataDictionary(controller.ViewData);

View File

@@ -93,5 +93,24 @@ namespace Umbraco.Web.Mvc
get { return _helper ?? (_helper = new UmbracoHelper(UmbracoContext)); }
}
/// <summary>
/// Ensure that the current view context is added to the route data tokens so we can extract it if we like
/// </summary>
/// <remarks>
/// Currently this is required by mvc macro engines
/// </remarks>
protected override void InitializePage()
{
base.InitializePage();
if (!ViewContext.IsChildAction)
{
if (!ViewContext.RouteData.DataTokens.ContainsKey(Constants.DataTokenCurrentViewContext))
{
ViewContext.RouteData.DataTokens.Add(Constants.DataTokenCurrentViewContext, this.ViewContext);
}
}
}
}
}

View File

@@ -1,3 +1,4 @@
using System.IO;
using System.Web.Mvc;
namespace Umbraco.Web.Mvc
@@ -30,5 +31,23 @@ namespace Umbraco.Web.Mvc
Writer = vc.Writer
};
}
//public static ViewContext CloneWithWriter(this ViewContext vc, TextWriter writer)
//{
// return new ViewContext
// {
// Controller = vc.Controller,
// HttpContext = vc.HttpContext,
// RequestContext = vc.RequestContext,
// RouteData = vc.RouteData,
// TempData = vc.TempData,
// View = vc.View,
// ViewData = vc.ViewData,
// FormContext = vc.FormContext,
// ClientValidationEnabled = vc.ClientValidationEnabled,
// UnobtrusiveJavaScriptEnabled = vc.UnobtrusiveJavaScriptEnabled,
// Writer = writer
// };
//}
}
}