我在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()
方法中的属性。但是,一旦进入方法内部,除了元素的名称之外,没有任何实际可以解决的问题,并且维护一个属性列表以标记为非可归属性将是一件非常令人头疼的事。我正在寻找更好的解决方案。