Search code examples
c#web-servicessoapwsdl

Create Webservice's datacontract dynamically


I have a webservice which needs to return data.

[DataMember]
public Int32 RequestId
{
    get { return requestId; }
    set { requestId = value; }
}

[DataMember]
public string StatusCode
{
    get { return statusCode; }
    set { statusCode = value; }
}

[DataMember]
public List<string> ErrorMessages
{
    get { return errorMessages; }
    set { errorMessages = value; }
}

[DataMember]
public string PeriodStatus
{
    get { return status; }
    set { status = value; }
}
[DataMember]
public string PhoneNumber
{
    get { return status; }
    set { status = value; }
}

Now some users of the service want to receive the phonenumber, others don't want to receive that field.

These preferences are stored in a database.

Is there a way to make the response dynamically based on whether they have chosen to receive the field or not?


Solution

  • I think you can't change returning data from service in runtime, because client has a batch of files including wsdl as description of web service. Evenmore , when web service has been modified , client need to update web references.

    In your case, when you don't know number of fields must be returning from service , you can return the collection of fields.

    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [XmlInclude(typeof(CustomFieldCollection))]
    [XmlInclude(typeof(CustomField))]
    [XmlInclude(typeof(CustomField[]))]
    public class Service : System.Web.Services.WebService
    {
    
        public Service()
        {
        }
    
        [WebMethod]
        public CustomFieldCollection GetFieldsCollection()
        {
            CustomFieldCollection collection = new CustomFieldCollection();
            collection["fieldA"] = 1;
            collection["fieldB"] = true;
            collection["fieldC"] = DateTime.Now;
            collection["fieldD"] = "hello";
            CustomFieldCollection collection1 = new CustomFieldCollection();
            collection1["fieldA"] = 1;
            collection1["fieldB"] = true;
            collection1["fieldC"] = DateTime.Now;
            collection1["fieldD"] = "hello";
            collection.Collection[0].CustomFields = collection1;
            return collection;
        }
    }
    public class CustomFieldCollection
    {
        private List<CustomField> fields = new List<CustomField>();
    
        public object this[String name]
        {
            get { return fields.FirstOrDefault(x => x.Name == name); }
            set
            {
                if (!fields.Exists(x => x.Name == name))
                {
                    fields.Add(new CustomField(name, value));
                }
                else
                {
                    this[name] = value;
                }
            }
        }
    
        public CustomField[] Collection
        {
            get { return fields.ToArray(); }
            set { }
        }
    }
    
    
    public class CustomField
    {
        public string Name { get; set; }
        public object Value { get; set; }
        public CustomFieldCollection CustomFields { get; set; }
    
        public CustomField()
        {
        }
    
        public CustomField(string name, object value)
        {
            Name = name;
            Value = value;
        }
    }
    

    You can modify GetFieldsCollection method, return collection of fields for specific type passed as parameter.