2

I found this service host here at SO (http://stackoverflow.com/questions/5801128/flat-wsdl-for-wcf-4-service) and I have used it to pin point a property of a class that I want to be nillable=false instead of the default true. I managed to do that but now need to implement some logic to automate this feature.

Host:

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) {}
    }
}

Now, it works in the sample project and I need to put this in the actual project with around 80 contracts and each complex enough to have many properties. Some are required and some are not. I need to figure out how I can automate the cancellation of nillable=true for the required ones. I was hoping the putting the [DataMember(IsRequired=True)] would help me locate the property in the WalkTheParticle() method above. However, once inside the method, there is no real thing I can relate to make this work except the element's name and it will be a real headache to maintain a list of properties to mark as non-nillable. I'm looking for a better solution.

DoomerDGR8
  • 4,840
  • 6
  • 43
  • 91

0 Answers0