HOW TO:匯出自訂的 WSDL
本主題將說明如何匯出自訂的 WSDL 資訊。為了要這麼做,我們定義了一個名為 WsdlDocumentationAttribute
的新程式碼屬性,會將自訂的資訊加入至服務所產生的 WSDL。
若要匯出自訂的 WSDL 資訊
請實作 IWsdlExportExtension 介面。您可以在實作下列任何介面的類別上實作此介面:IOperationBehavior、IContractBehavior 或 IEndpointBehavior。您也可以在衍生自 BindingElement 的類別上實作此介面。此範例在實作 IContractBehavior 的屬性類別上實作了 IWsdlExportExtension。
IWsdlExportExtension 定義了兩個方法:ExportEndpoint 和 ExportContract。這些方法可讓您修改或加入 (或修改和加入) 額外的資訊至 WsdlContractConversionContext。這個範例的 ExportContract 方法中,擷取了 OperationDescription 物件的集合,接著並逐一查看集合,檢查是否有
WsdlDocumentationAttribute
。如果找到任何一個,則會擷取與屬性關聯的文字、產生摘要項目,並將摘要項目加入至作業的DocumentationElement
。public void ExportContract(WsdlExporter exporter, WsdlContractConversionContext context) { Console.WriteLine("Inside ExportContract"); if (context.Contract != null) { // Set the document element; if this is not done first, there is no XmlElement in the // DocumentElement property. context.WsdlPortType.Documentation = string.Empty; // Contract comments. XmlDocument owner = context.WsdlPortType.DocumentationElement.OwnerDocument; XmlElement summaryElement = Formatter.CreateSummaryElement(owner, this.Text); context.WsdlPortType.DocumentationElement.AppendChild(summaryElement); foreach (OperationDescription op in context.Contract.Operations) { Operation operation = context.GetOperation(op); object[] opAttrs = op.SyncMethod.GetCustomAttributes(typeof(WsdlDocumentationAttribute), false); if (opAttrs.Length == 1) { string opComment = ((WsdlDocumentationAttribute)opAttrs[0]).Text; // This.Text returns the string for the operation-level attributes. // Set the doc element; if this is not done first, there is no XmlElement in the // DocumentElement property. operation.Documentation = String.Empty; XmlDocument opOwner = operation.DocumentationElement.OwnerDocument; XmlElement newSummaryElement = Formatter.CreateSummaryElement(opOwner, opComment); operation.DocumentationElement.AppendChild(newSummaryElement); } } }
範例
下列程式碼範例顯示 WsdlDocumentationAttribute
類別的完整實作。
public class WsdlDocumentationAttribute : Attribute, IContractBehavior, IWsdlExportExtension
{
string text;
XmlElement customWsdlDocElement = null;
public WsdlDocumentationAttribute(string text)
{ this.text = text;}
public WsdlDocumentationAttribute(XmlElement wsdlDocElement)
{ this.customWsdlDocElement = wsdlDocElement; }
public XmlElement WsdlDocElement
{
get { return this.customWsdlDocElement; }
set { this.customWsdlDocElement = value; }
}
public string Text
{
get { return this.text; }
set { this.text = value; }
}
public void ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
{
Console.WriteLine("Inside ExportContract");
if (context.Contract != null)
{
// Set the document element; if this is not done first, there is no XmlElement in the
// DocumentElement property.
context.WsdlPortType.Documentation = string.Empty;
// Contract comments.
XmlDocument owner = context.WsdlPortType.DocumentationElement.OwnerDocument;
XmlElement summaryElement = Formatter.CreateSummaryElement(owner, this.Text);
context.WsdlPortType.DocumentationElement.AppendChild(summaryElement);
foreach (OperationDescription op in context.Contract.Operations)
{
Operation operation = context.GetOperation(op);
object[] opAttrs = op.SyncMethod.GetCustomAttributes(typeof(WsdlDocumentationAttribute), false);
if (opAttrs.Length == 1)
{
string opComment = ((WsdlDocumentationAttribute)opAttrs[0]).Text;
// This.Text returns the string for the operation-level attributes.
// Set the document element; if this is not done first, there is no XmlElement in the
// DocumentElement property.
operation.Documentation = String.Empty;
XmlDocument opOwner = operation.DocumentationElement.OwnerDocument;
XmlElement newSummaryElement = Formatter.CreateSummaryElement(opOwner, opComment);
operation.DocumentationElement.AppendChild(newSummaryElement);
}
}
}
}
public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
{
Console.WriteLine("ExportEndpoint called.");
}
public void AddBindingParameters(ContractDescription description, ServiceEndpoint endpoint, BindingParameterCollection parameters)
{ return; }
public void ApplyClientBehavior(ContractDescription description, ServiceEndpoint endpoint, ClientRuntime client)
{ return; }
public void ApplyDispatchBehavior(ContractDescription description, ServiceEndpoint endpoint, DispatchRuntime dispatch)
{ return; }
public void Validate(ContractDescription description, ServiceEndpoint endpoint) { return; }
}
public class Formatter
{
#region Utility Functions
public static XmlElement CreateSummaryElement(XmlDocument owningDoc, string text)
{
XmlElement summaryElement = owningDoc.CreateElement("summary");
summaryElement.InnerText = text;
return summaryElement;
}
public static CodeCommentStatementCollection FormatComments(string text)
{
/*
* Note that in Visual C# the XML comment format absorbs a
* documentation element with a line break in the middle. This sample
* could take an XmlElement and create code comments in which
* the element never had a line break in it.
*/
CodeCommentStatementCollection collection = new CodeCommentStatementCollection();
collection.Add(new CodeCommentStatement("From WsdlDocumentation:", true));
collection.Add(new CodeCommentStatement(String.Empty, true));
foreach (string line in WordWrap(text, 80))
{
collection.Add(new CodeCommentStatement(line, true));
}
collection.Add(new CodeCommentStatement(String.Empty, true));
return collection;
}
public static Collection<string> WordWrap(string text, int columnWidth)
{
Collection<string> lines = new Collection<string>();
System.Text.StringBuilder builder = new System.Text.StringBuilder();
string[] words = text.Split(' ');
foreach (string word in words)
{
if ((builder.Length > 0) && ((builder.Length + word.Length + 1) > columnWidth))
{
lines.Add(builder.ToString());
builder = new System.Text.StringBuilder();
}
builder.Append(word);
builder.Append(' ');
}
lines.Add(builder.ToString());
return lines;
}
#endregion
public static XmlElement CreateReturnsElement(XmlDocument owner, string p)
{
XmlElement returnsElement = owner.CreateElement("returns");
returnsElement.InnerText = p;
return returnsElement;
}
}