428 lines
22 KiB
C#
428 lines
22 KiB
C#
|
//-----------------------------------------------------------------------------
|
|||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
namespace System.ServiceModel.Dispatcher
|
|||
|
{
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.IO;
|
|||
|
using System.Linq;
|
|||
|
using System.Net;
|
|||
|
using System.Runtime.Serialization.Json;
|
|||
|
using System.ServiceModel.Description;
|
|||
|
using System.ServiceModel.Web;
|
|||
|
using System.ServiceModel.Web.Configuration;
|
|||
|
using System.Text;
|
|||
|
using System.Xml;
|
|||
|
using System.Xml.Linq;
|
|||
|
using System.Globalization;
|
|||
|
using System.Web;
|
|||
|
using System.Xml.Schema;
|
|||
|
|
|||
|
class HelpHtmlBuilder
|
|||
|
{
|
|||
|
const string HelpOperationPageUrl = "help/operations/{0}";
|
|||
|
const string HtmlHtmlElementName = "{http://www.w3.org/1999/xhtml}html";
|
|||
|
const string HtmlHeadElementName = "{http://www.w3.org/1999/xhtml}head";
|
|||
|
const string HtmlTitleElementName = "{http://www.w3.org/1999/xhtml}title";
|
|||
|
const string HtmlBodyElementName = "{http://www.w3.org/1999/xhtml}body";
|
|||
|
const string HtmlBrElementName = "{http://www.w3.org/1999/xhtml}br";
|
|||
|
const string HtmlPElementName = "{http://www.w3.org/1999/xhtml}p";
|
|||
|
const string HtmlTableElementName = "{http://www.w3.org/1999/xhtml}table";
|
|||
|
const string HtmlTrElementName = "{http://www.w3.org/1999/xhtml}tr";
|
|||
|
const string HtmlThElementName = "{http://www.w3.org/1999/xhtml}th";
|
|||
|
const string HtmlTdElementName = "{http://www.w3.org/1999/xhtml}td";
|
|||
|
const string HtmlDivElementName = "{http://www.w3.org/1999/xhtml}div";
|
|||
|
const string HtmlAElementName = "{http://www.w3.org/1999/xhtml}a";
|
|||
|
const string HtmlPreElementName = "{http://www.w3.org/1999/xhtml}pre";
|
|||
|
const string HtmlClassAttributeName = "class";
|
|||
|
const string HtmlTitleAttributeName = "title";
|
|||
|
const string HtmlHrefAttributeName = "href";
|
|||
|
const string HtmlRelAttributeName = "rel";
|
|||
|
const string HtmlIdAttributeName = "id";
|
|||
|
const string HtmlNameAttributeName = "name";
|
|||
|
const string HtmlRowspanAttributeName = "rowspan";
|
|||
|
const string HtmlHeading1Class = "heading1";
|
|||
|
const string HtmlContentClass = "content";
|
|||
|
|
|||
|
const string HtmlRequestXmlId = "request-xml";
|
|||
|
const string HtmlRequestJsonId = "request-json";
|
|||
|
const string HtmlRequestSchemaId = "request-schema";
|
|||
|
const string HtmlResponseXmlId = "response-xml";
|
|||
|
const string HtmlResponseJsonId = "response-json";
|
|||
|
const string HtmlResponseSchemaId = "response-schema";
|
|||
|
const string HtmlOperationClass = "operation";
|
|||
|
|
|||
|
public static XDocument CreateHelpPage(Uri baseUri, IEnumerable<OperationHelpInformation> operations)
|
|||
|
{
|
|||
|
XDocument document = CreateBaseDocument(SR2.GetString(SR2.HelpPageOperationsAt, baseUri));
|
|||
|
XElement table = new XElement(HtmlTableElementName,
|
|||
|
new XElement(HtmlTrElementName,
|
|||
|
new XElement(HtmlThElementName, SR2.GetString(SR2.HelpPageUri)),
|
|||
|
new XElement(HtmlThElementName, SR2.GetString(SR2.HelpPageMethod)),
|
|||
|
new XElement(HtmlThElementName, SR2.GetString(SR2.HelpPageDescription))));
|
|||
|
|
|||
|
string lastOperation = null;
|
|||
|
XElement firstTr = null;
|
|||
|
int rowspan = 0;
|
|||
|
foreach (OperationHelpInformation operationHelpInfo in operations.OrderBy(o => FilterQueryVariables(o.UriTemplate)))
|
|||
|
{
|
|||
|
string operationUri = FilterQueryVariables(operationHelpInfo.UriTemplate);
|
|||
|
string description = operationHelpInfo.Description;
|
|||
|
if (String.IsNullOrEmpty(description))
|
|||
|
{
|
|||
|
description = SR2.GetString(SR2.HelpPageDefaultDescription, BuildFullUriTemplate(baseUri, operationHelpInfo.UriTemplate));
|
|||
|
}
|
|||
|
XElement tr = new XElement(HtmlTrElementName,
|
|||
|
new XElement(HtmlTdElementName, new XAttribute(HtmlTitleAttributeName, BuildFullUriTemplate(baseUri, operationHelpInfo.UriTemplate)),
|
|||
|
new XElement(HtmlAElementName,
|
|||
|
new XAttribute(HtmlRelAttributeName, HtmlOperationClass),
|
|||
|
new XAttribute(HtmlHrefAttributeName, String.Format(CultureInfo.InvariantCulture, HelpOperationPageUrl, operationHelpInfo.Name)), operationHelpInfo.Method)),
|
|||
|
new XElement(HtmlTdElementName, description));
|
|||
|
table.Add(tr);
|
|||
|
if (operationUri != lastOperation)
|
|||
|
{
|
|||
|
XElement td = new XElement(HtmlTdElementName, operationUri == lastOperation ? String.Empty : operationUri);
|
|||
|
tr.AddFirst(td);
|
|||
|
if (firstTr != null && rowspan > 1)
|
|||
|
{
|
|||
|
firstTr.Descendants(HtmlTdElementName).First().Add(new XAttribute(HtmlRowspanAttributeName, rowspan));
|
|||
|
}
|
|||
|
firstTr = tr;
|
|||
|
rowspan = 0;
|
|||
|
lastOperation = operationUri;
|
|||
|
}
|
|||
|
++rowspan;
|
|||
|
}
|
|||
|
if (firstTr != null && rowspan > 1)
|
|||
|
{
|
|||
|
firstTr.Descendants(HtmlTdElementName).First().Add(new XAttribute(HtmlRowspanAttributeName, rowspan));
|
|||
|
}
|
|||
|
document.Descendants(HtmlBodyElementName).First().Add(new XElement(HtmlDivElementName, new XAttribute(HtmlIdAttributeName, HtmlContentClass),
|
|||
|
new XElement(HtmlPElementName, new XAttribute(HtmlClassAttributeName, HtmlHeading1Class), SR2.GetString(SR2.HelpPageOperationsAt, baseUri)),
|
|||
|
new XElement(HtmlPElementName, SR2.GetString(SR2.HelpPageStaticText)),
|
|||
|
table));
|
|||
|
return document;
|
|||
|
}
|
|||
|
|
|||
|
public static XDocument CreateOperationHelpPage(Uri baseUri, OperationHelpInformation operationInfo)
|
|||
|
{
|
|||
|
XDocument document = CreateBaseDocument(SR2.GetString(SR2.HelpPageReferenceFor, BuildFullUriTemplate(baseUri, operationInfo.UriTemplate)));
|
|||
|
XElement table = new XElement(HtmlTableElementName,
|
|||
|
new XElement(HtmlTrElementName,
|
|||
|
new XElement(HtmlThElementName, SR2.GetString(SR2.HelpPageMessageDirection)),
|
|||
|
new XElement(HtmlThElementName, SR2.GetString(SR2.HelpPageFormat)),
|
|||
|
new XElement(HtmlThElementName, SR2.GetString(SR2.HelpPageBody))));
|
|||
|
|
|||
|
RenderMessageInformation(table, operationInfo, true);
|
|||
|
RenderMessageInformation(table, operationInfo, false);
|
|||
|
|
|||
|
XElement div = new XElement(HtmlDivElementName, new XAttribute(HtmlIdAttributeName, HtmlContentClass),
|
|||
|
new XElement(HtmlPElementName, new XAttribute(HtmlClassAttributeName, HtmlHeading1Class), SR2.GetString(SR2.HelpPageReferenceFor, BuildFullUriTemplate(baseUri, operationInfo.UriTemplate))),
|
|||
|
new XElement(HtmlPElementName, operationInfo.Description),
|
|||
|
XElement.Parse(SR2.GetString(SR2.HelpPageOperationUri, HttpUtility.HtmlEncode(BuildFullUriTemplate(baseUri, operationInfo.UriTemplate)))),
|
|||
|
XElement.Parse(SR2.GetString(SR2.HelpPageOperationMethod, HttpUtility.HtmlEncode(operationInfo.Method))));
|
|||
|
if (!String.IsNullOrEmpty(operationInfo.JavascriptCallbackParameterName))
|
|||
|
{
|
|||
|
div.Add(XElement.Parse(SR2.GetString(SR2.HelpPageCallbackText, HttpUtility.HtmlEncode(operationInfo.JavascriptCallbackParameterName))), table);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
div.Add(table);
|
|||
|
}
|
|||
|
document.Descendants(HtmlBodyElementName).First().Add(div);
|
|||
|
|
|||
|
CreateOperationSamples(document.Descendants(HtmlDivElementName).First(), operationInfo);
|
|||
|
|
|||
|
return document;
|
|||
|
}
|
|||
|
|
|||
|
public static XDocument CreateMethodNotAllowedPage(Uri helpUri)
|
|||
|
{
|
|||
|
XDocument document = CreateBaseDocument(SR2.GetString(SR2.HelpPageTitleText));
|
|||
|
|
|||
|
XElement div = new XElement(HtmlDivElementName, new XAttribute(HtmlIdAttributeName, HtmlContentClass),
|
|||
|
new XElement(HtmlPElementName, new XAttribute(HtmlClassAttributeName, HtmlHeading1Class), SR2.GetString(SR2.HelpPageTitleText)));
|
|||
|
if (helpUri == null)
|
|||
|
{
|
|||
|
div.Add(new XElement(HtmlPElementName, SR2.GetString(SR2.HelpPageMethodNotAllowed)));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
div.Add(XElement.Parse(SR2.GetString(SR2.HelpPageMethodNotAllowedWithLink, HttpUtility.HtmlEncode(helpUri.AbsoluteUri))));
|
|||
|
}
|
|||
|
document.Descendants(HtmlBodyElementName).First().Add(div);
|
|||
|
return document;
|
|||
|
}
|
|||
|
|
|||
|
public static XDocument CreateServerErrorPage(Uri helpUri, Exception error)
|
|||
|
{
|
|||
|
XDocument document = CreateBaseDocument(SR2.GetString(SR2.HelpPageRequestErrorTitle));
|
|||
|
|
|||
|
XElement div = new XElement(HtmlDivElementName, new XAttribute(HtmlIdAttributeName, HtmlContentClass),
|
|||
|
new XElement(HtmlPElementName, new XAttribute(HtmlClassAttributeName, HtmlHeading1Class), SR2.GetString(SR2.HelpPageRequestErrorTitle)));
|
|||
|
if (helpUri == null)
|
|||
|
{
|
|||
|
if (error != null)
|
|||
|
{
|
|||
|
//TFS Bug 500275: it is not necessary to HtmlEncode the error.Message string here because XElement ctor will encode it.
|
|||
|
div.Add(new XElement(HtmlPElementName, SR2.GetString(SR2.HelpServerErrorProcessingRequestWithDetails, error.Message)));
|
|||
|
div.Add(new XElement(HtmlPElementName, error.StackTrace ?? String.Empty));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
div.Add(new XElement(HtmlPElementName, SR2.GetString(SR2.HelpServerErrorProcessingRequest)));
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
string encodedHelpLink = HttpUtility.HtmlEncode(helpUri.AbsoluteUri);
|
|||
|
if (error != null)
|
|||
|
{
|
|||
|
//TFS Bug 500275: XElement.Parse does not HtmlEncode the string passed to it, so we need to encode it before calling Parse.
|
|||
|
string errorMessage = AppSettings.DisableHtmlErrorPageExceptionHtmlEncoding ? error.Message : HttpUtility.HtmlEncode(error.Message);
|
|||
|
div.Add(XElement.Parse(SR2.GetString(SR2.HelpServerErrorProcessingRequestWithDetailsAndLink, encodedHelpLink, errorMessage)));
|
|||
|
div.Add(new XElement(HtmlPElementName, error.StackTrace ?? String.Empty));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
div.Add(XElement.Parse(SR2.GetString(SR2.HelpServerErrorProcessingRequestWithLink, encodedHelpLink)));
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
document.Descendants(HtmlBodyElementName).First().Add(div);
|
|||
|
return document;
|
|||
|
}
|
|||
|
|
|||
|
public static XDocument CreateEndpointNotFound(Uri helpUri)
|
|||
|
{
|
|||
|
XDocument document = CreateBaseDocument(SR2.GetString(SR2.HelpPageTitleText));
|
|||
|
|
|||
|
XElement div = new XElement(HtmlDivElementName, new XAttribute(HtmlIdAttributeName, HtmlContentClass),
|
|||
|
new XElement(HtmlPElementName, new XAttribute(HtmlClassAttributeName, HtmlHeading1Class), SR2.GetString(SR2.HelpPageTitleText)));
|
|||
|
if (helpUri == null)
|
|||
|
{
|
|||
|
div.Add(new XElement(HtmlPElementName, SR2.GetString(SR2.HelpPageEndpointNotFound)));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
div.Add(XElement.Parse(SR2.GetString(SR2.HelpPageEndpointNotFoundWithLink, HttpUtility.HtmlEncode(helpUri.AbsoluteUri))));
|
|||
|
}
|
|||
|
document.Descendants(HtmlBodyElementName).First().Add(div);
|
|||
|
return document;
|
|||
|
}
|
|||
|
|
|||
|
public static XDocument CreateTransferRedirectPage(string originalTo, string newLocation)
|
|||
|
{
|
|||
|
XDocument document = CreateBaseDocument(SR2.GetString(SR2.HelpPageTitleText));
|
|||
|
|
|||
|
XElement div = new XElement(HtmlDivElementName, new XAttribute(HtmlIdAttributeName, HtmlContentClass),
|
|||
|
new XElement(HtmlPElementName, new XAttribute(HtmlClassAttributeName, HtmlHeading1Class), SR2.GetString(SR2.HelpPageTitleText)),
|
|||
|
XElement.Parse(SR2.GetString(SR2.HelpPageRedirect, HttpUtility.HtmlEncode(originalTo), HttpUtility.HtmlEncode(newLocation))));
|
|||
|
document.Descendants(HtmlBodyElementName).First().Add(div);
|
|||
|
return document;
|
|||
|
}
|
|||
|
|
|||
|
static XDocument CreateBaseDocument(string title)
|
|||
|
{
|
|||
|
return new XDocument(
|
|||
|
new XDocumentType("html", "-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", null),
|
|||
|
new XElement(HtmlHtmlElementName,
|
|||
|
new XElement(HtmlHeadElementName,
|
|||
|
new XElement(HtmlTitleElementName, title),
|
|||
|
new XElement("{http://www.w3.org/1999/xhtml}style", SR2.GetString(SR2.HelpPageHtml))),
|
|||
|
new XElement(HtmlBodyElementName)));
|
|||
|
}
|
|||
|
|
|||
|
static string FilterQueryVariables(string uriTemplate)
|
|||
|
{
|
|||
|
int variablesIndex = uriTemplate.IndexOf('?');
|
|||
|
if (variablesIndex > 0)
|
|||
|
{
|
|||
|
return uriTemplate.Substring(0, variablesIndex);
|
|||
|
}
|
|||
|
return uriTemplate;
|
|||
|
}
|
|||
|
|
|||
|
static void RenderMessageInformation(XElement table, OperationHelpInformation operationInfo, bool isRequest)
|
|||
|
{
|
|||
|
MessageHelpInformation info = isRequest ? operationInfo.Request : operationInfo.Response;
|
|||
|
string direction = isRequest ? SR2.GetString(SR2.HelpPageRequest) : SR2.GetString(SR2.HelpPageResponse);
|
|||
|
string nonLocalizedDirection = isRequest ? HtmlRequestXmlId : HtmlResponseXmlId;
|
|||
|
|
|||
|
if (info.BodyDescription != null)
|
|||
|
{
|
|||
|
table.Add(new XElement(HtmlTrElementName,
|
|||
|
new XElement(HtmlTdElementName, direction),
|
|||
|
new XElement(HtmlTdElementName, info.FormatString),
|
|||
|
new XElement(HtmlTdElementName, info.BodyDescription)));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (info.XmlExample != null || info.Schema != null)
|
|||
|
{
|
|||
|
XElement contentTd;
|
|||
|
table.Add(new XElement(HtmlTrElementName,
|
|||
|
new XElement(HtmlTdElementName, direction),
|
|||
|
new XElement(HtmlTdElementName, "Xml"),
|
|||
|
contentTd = new XElement(HtmlTdElementName)));
|
|||
|
|
|||
|
if (info.XmlExample != null)
|
|||
|
{
|
|||
|
contentTd.Add(new XElement(HtmlAElementName, new XAttribute(HtmlHrefAttributeName, "#" + (isRequest ? HtmlRequestXmlId : HtmlResponseXmlId)), SR2.GetString(SR2.HelpPageExample)));
|
|||
|
if (info.Schema != null)
|
|||
|
{
|
|||
|
contentTd.Add(",");
|
|||
|
}
|
|||
|
}
|
|||
|
if (info.Schema != null)
|
|||
|
{
|
|||
|
contentTd.Add(new XElement(HtmlAElementName, new XAttribute(HtmlHrefAttributeName, "#" + (isRequest ? HtmlRequestSchemaId : HtmlResponseSchemaId)), SR2.GetString(SR2.HelpPageSchema)));
|
|||
|
}
|
|||
|
}
|
|||
|
if (info.JsonExample != null)
|
|||
|
{
|
|||
|
table.Add(new XElement(HtmlTrElementName,
|
|||
|
new XElement(HtmlTdElementName, direction),
|
|||
|
new XElement(HtmlTdElementName, "Json"),
|
|||
|
new XElement(HtmlTdElementName,
|
|||
|
new XElement(HtmlAElementName, new XAttribute(HtmlHrefAttributeName, "#" + (isRequest ? HtmlRequestJsonId : HtmlResponseJsonId)), SR2.GetString(SR2.HelpPageExample)))));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static void CreateOperationSamples(XElement element, OperationHelpInformation operationInfo)
|
|||
|
{
|
|||
|
if (operationInfo.Request.XmlExample != null)
|
|||
|
{
|
|||
|
element.Add(GenerateSampleXml(operationInfo.Request.XmlExample, SR2.GetString(SR2.HelpPageXmlRequest), HtmlRequestXmlId));
|
|||
|
}
|
|||
|
if (operationInfo.Request.JsonExample != null)
|
|||
|
{
|
|||
|
element.Add(AddSampleJson(operationInfo.Request.JsonExample, SR2.GetString(SR2.HelpPageJsonRequest), HtmlRequestJsonId));
|
|||
|
}
|
|||
|
if (operationInfo.Response.XmlExample != null)
|
|||
|
{
|
|||
|
element.Add(GenerateSampleXml(operationInfo.Response.XmlExample, SR2.GetString(SR2.HelpPageXmlResponse), HtmlResponseXmlId));
|
|||
|
}
|
|||
|
if (operationInfo.Response.JsonExample != null)
|
|||
|
{
|
|||
|
element.Add(AddSampleJson(operationInfo.Response.JsonExample, SR2.GetString(SR2.HelpPageJsonResponse), HtmlResponseJsonId));
|
|||
|
}
|
|||
|
|
|||
|
if (operationInfo.Request.Schema != null)
|
|||
|
{
|
|||
|
element.Add(GenerateSampleXml(XmlSchemaToXElement(operationInfo.Request.Schema), SR2.GetString(SR2.HelpPageRequestSchema), HtmlRequestSchemaId));
|
|||
|
int count = 0;
|
|||
|
foreach (XmlSchema schema in operationInfo.Request.SchemaSet.Schemas())
|
|||
|
{
|
|||
|
if (schema.TargetNamespace != operationInfo.Request.Schema.TargetNamespace)
|
|||
|
{
|
|||
|
element.Add(GenerateSampleXml(XmlSchemaToXElement(schema), ++count == 1 ? SR2.GetString(SR2.HelpPageAdditionalRequestSchema) : null, HtmlRequestSchemaId));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (operationInfo.Response.Schema != null)
|
|||
|
{
|
|||
|
element.Add(GenerateSampleXml(XmlSchemaToXElement(operationInfo.Response.Schema), SR2.GetString(SR2.HelpPageResponseSchema), HtmlResponseSchemaId));
|
|||
|
int count = 0;
|
|||
|
foreach (XmlSchema schema in operationInfo.Response.SchemaSet.Schemas())
|
|||
|
{
|
|||
|
if (schema.TargetNamespace != operationInfo.Response.Schema.TargetNamespace)
|
|||
|
{
|
|||
|
element.Add(GenerateSampleXml(XmlSchemaToXElement(schema), ++count == 1 ? SR2.GetString(SR2.HelpPageAdditionalResponseSchema) : null, HtmlResponseSchemaId));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static XElement XmlSchemaToXElement(XmlSchema schema)
|
|||
|
{
|
|||
|
XmlWriterSettings settings = new XmlWriterSettings
|
|||
|
{
|
|||
|
CloseOutput = false,
|
|||
|
Indent = true,
|
|||
|
};
|
|||
|
|
|||
|
XDocument schemaDocument = new XDocument();
|
|||
|
|
|||
|
using (XmlWriter writer = XmlWriter.Create(schemaDocument.CreateWriter(), settings))
|
|||
|
{
|
|||
|
schema.Write(writer);
|
|||
|
}
|
|||
|
return schemaDocument.Root;
|
|||
|
}
|
|||
|
|
|||
|
static XElement AddSample(object content, string title, string label)
|
|||
|
{
|
|||
|
if (String.IsNullOrEmpty(title))
|
|||
|
{
|
|||
|
return new XElement(HtmlPElementName,
|
|||
|
new XElement(HtmlPreElementName, new XAttribute(HtmlClassAttributeName, label), content));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return new XElement(HtmlPElementName,
|
|||
|
new XElement(HtmlAElementName, new XAttribute(HtmlNameAttributeName, label), title),
|
|||
|
new XElement(HtmlPreElementName, new XAttribute(HtmlClassAttributeName, label), content));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static XElement GenerateSampleXml(XElement content, string title, string label)
|
|||
|
{
|
|||
|
StringBuilder sample = new StringBuilder();
|
|||
|
using (XmlWriter writer = XmlTextWriter.Create(sample, new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true }))
|
|||
|
{
|
|||
|
content.WriteTo(writer);
|
|||
|
}
|
|||
|
return AddSample(sample.ToString(), title, label);
|
|||
|
}
|
|||
|
|
|||
|
static XElement AddSampleJson(XElement content, string title, string label)
|
|||
|
{
|
|||
|
StringBuilder sample = new StringBuilder();
|
|||
|
using (MemoryStream stream = new MemoryStream())
|
|||
|
{
|
|||
|
using (XmlJsonWriter writer = new XmlJsonWriter())
|
|||
|
{
|
|||
|
writer.SetOutput(stream, Encoding.Unicode, false);
|
|||
|
content.WriteTo(writer);
|
|||
|
}
|
|||
|
stream.Position = 0;
|
|||
|
sample.Append(new StreamReader(stream, Encoding.Unicode).ReadToEnd());
|
|||
|
}
|
|||
|
int depth = 0;
|
|||
|
bool inString = false;
|
|||
|
for (int i = 0; i < sample.Length; ++i)
|
|||
|
{
|
|||
|
if (sample[i] == '"')
|
|||
|
{
|
|||
|
inString = !inString;
|
|||
|
}
|
|||
|
else if (sample[i] == '{')
|
|||
|
{
|
|||
|
sample.Insert(i + 1, "\n" + new String('\t', ++depth));
|
|||
|
i += depth + 1;
|
|||
|
}
|
|||
|
else if (sample[i] == ',' && !inString)
|
|||
|
{
|
|||
|
sample.Insert(i + 1, "\n" + new String('\t', depth));
|
|||
|
}
|
|||
|
else if (sample[i] == '}' && depth > 0)
|
|||
|
{
|
|||
|
sample.Insert(i, "\n" + new String('\t', --depth));
|
|||
|
i += depth + 1;
|
|||
|
}
|
|||
|
}
|
|||
|
return AddSample(sample.ToString(), title, label);
|
|||
|
}
|
|||
|
|
|||
|
static string BuildFullUriTemplate(Uri baseUri, string uriTemplate)
|
|||
|
{
|
|||
|
UriTemplate template = new UriTemplate(uriTemplate);
|
|||
|
Uri result = template.BindByPosition(baseUri, template.PathSegmentVariableNames.Concat(template.QueryValueVariableNames).Select(name => "{" + name + "}").ToArray());
|
|||
|
return result.ToString();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|