我在 SO (http://stackoverflow.com/questions/5801128/flat-wsdl-for-wcf-4-service) 找到了这个服务主机,我用它来确定我想要的类的属性是 nillable=false 而不是默认的 true。我设法做到了,但现在需要实现一些逻辑来自动化这个功能。
主持人:
using System;
using System.Collections;
using System.Collections.Generic;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Xml.Schema;
using ServiceDescription = System.Web.Services.Description.ServiceDescription;
namespace Thinktecture.ServiceModel.Extensions.Description {
public class FlatWsdl : IWsdlExportExtension, IEndpointBehavior {
public void ExportContract(WsdlExporter exporter, WsdlContractConversionContext context) {}
public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context) {
XmlSchemaSet schemaSet = exporter.GeneratedXmlSchemas;
ProcessNillable(schemaSet);
...
...
}
private static void WalkTheParticle(XmlSchemaParticle particle)
{
if (particle is XmlSchemaElement) {
XmlSchemaElement elem = particle as XmlSchemaElement;
Console.WriteLine(elem.Name);
if (elem != null && String.Compare(elem.Name, "name", false) == 0)
{
elem.IsNillable = false; //This works!
Console.WriteLine("Bazinga!");
}
if (elem.RefName.IsEmpty) {
XmlSchemaType type = (XmlSchemaType)elem.ElementSchemaType;
if (type is XmlSchemaComplexType) {
XmlSchemaComplexType ct = type as XmlSchemaComplexType;
if (ct.QualifiedName.IsEmpty) {
WalkTheParticle(ct.ContentTypeParticle);
}
}
}
}
else if (particle is XmlSchemaGroupBase)
//xs:all, xs:choice, xs:sequence
{
XmlSchemaGroupBase baseParticle = particle as XmlSchemaGroupBase;
foreach (XmlSchemaParticle subParticle in baseParticle.Items)
{
WalkTheParticle(subParticle);
}
}
}
private static void AddImportedSchemas(XmlSchema schema, XmlSchemaSet schemaSet, List<XmlSchema> importsList) { ... }
private static void RemoveXsdImports(XmlSchema schema) { ... }
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) {}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) {}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) {}
public void Validate(ServiceEndpoint endpoint) {}
}
}
现在,它可以在示例项目中使用,我需要将其放入实际项目中,其中包含大约 80 个合同,每个合同都足够复杂以拥有许多属性。有些是必需的,有些不是。我需要弄清楚如何自动取消所需的 nillable=true 。我希望放置[DataMember(IsRequired=True)]
可以帮助我在上述WalkTheParticle()
方法中找到该属性。但是,一旦进入该方法,除了元素的名称之外,我没有其他真正的东西可以让这项工作发挥作用,维护一个属性列表以标记为不可空是一件真正令人头疼的事情。我正在寻找更好的解决方案。