vendredi 22 mai 2015

Trying to make a generic Xml

I'm trying to make a method to create a soap envelope that has to be generic. Basically, what it does is receives a DTO file, reads a xml file with the soap and fills it with the values from the DTO. I have two DTO's for the moment but there will be more. I use Reflection to get the values from the DTO and fill the xml file. It works fine for one of the xml files, but I'm struggling to get it to work for the second one.

These are my XML files

It works fine with this one

<soap:Envelope xmlns:soap="http://ift.tt/sVJIaE">
  <soap:Body>
    <GetStreamsForEvent xmlns="...">
      <customerUID></customerUID>
      <eventId></eventId>
    </GetStreamsForEvent>
  </soap:Body>
</soap:Envelope>

Doesn't work with this one

<soap:Envelope xmlns:soap="http://ift.tt/sVJIaE">
  <soap:Body>
    <soap:Envelope xmlns:soap="http://ift.tt/sVJIaE">
  <soap:Body>
    <GenerateEventView xmlns="...">
      <igmStreamInput>
        <CustomerUID></CustomerUID>
        <UserIdentifier></UserIdentifier>
        <UserIPAddress></UserIPAddress>
        <EventID></EventID>
        <UniqueStreamName</UniqueStreamName>
        <RedirectURL></RedirectURL>
      </igmStreamInput>
    </GenerateEventView>
  </soap:Body>
</soap:Envelope>
  </soap:Body>
</soap:Envelope>

These are my DTO's

namespace TestServerIGMToken
{
    public class GetStreamsForEventDTO
    {
        /// <summary>
        /// 
        /// </summary>
        public string customerUID { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string eventId { get; set; }
    }
}


namespace TestServerIGMToken
{
    /// <summary>
    /// 
    /// </summary>
    public class GenerateEventViewDTO
    {
        ///// <summary>
        ///// 
        ///// </summary>
        //public string igmStreamInput { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string customerUID { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string UserIdentifier { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string UserIPAddress { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string EventID { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string UniqueStreamName { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string RedirectURL { get; set; }       
    }
}

These is my code

This function receives T streamsForEvent, shich can be one of the two DTO's. It creates a webrequest, fills the soap xml with values from the DTO, puts it in a stream and reads from it.

 /// <summary>
        /// 
        /// </summary>
        /// <param name="streamsForEvent"></param>
        /// <returns></returns>
        private string GetStreamsForEventProcess<T>(T streamsForEvent)
        {
            try
            {
                string getUri = GenericHelperMethods.GetResourceString(streamsForEvent, Resources.Uri);
                string getAction = GenericHelperMethods.GetResourceString(streamsForEvent, Resources.Action);

                HttpWebRequest getStreamsForEventWebRequest = CreateWebRequest(getUri, getAction);
                InsertSoapEnvelopeIntoWebRequest(GenericSoap.CreateSoapEnvelope(streamsForEvent), getStreamsForEventWebRequest);

                IAsyncResult asyncResult = getStreamsForEventWebRequest.BeginGetResponse(null, null);
                asyncResult.AsyncWaitHandle.WaitOne();

                using (WebResponse getStreamsForEventWebResponse = getStreamsForEventWebRequest.EndGetResponse(asyncResult))
                {
                    using (StreamReader getStreamsForEventStreamReader = new StreamReader(getStreamsForEventWebResponse.GetResponseStream()))
                    {
                        return getStreamsForEventStreamReader.ReadToEnd();
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

This method creates the webrequest

/// <summary>
        /// 
        /// </summary>
        /// <param name="getStreamsForEventUri"></param>
        /// <param name="getStreamsForEventAction"></param>
        /// <returns></returns>
        private static HttpWebRequest CreateWebRequest(string getStreamsForEventUri, string getStreamsForEventAction)
        {
            HttpWebRequest getStreamsForEventWebRequest = WebRequest.Create(getStreamsForEventUri) as HttpWebRequest;
            getStreamsForEventWebRequest.Headers.Add("SOAPAction", getStreamsForEventAction);
            getStreamsForEventWebRequest.ContentType = "text/xml;charset=\"utf-8\"";
            getStreamsForEventWebRequest.Accept = "text/xml";
            getStreamsForEventWebRequest.Method = "POST";

            return getStreamsForEventWebRequest;
        }

This method inserts soap envelop into the stream

/// <summary>
        /// 
        /// </summary>
        /// <param name="getStreamsForEventSoapEnvelope"></param>
        /// <param name="getStreamsForEventWebRequest"></param>
        private static void InsertSoapEnvelopeIntoWebRequest(XmlDocument getStreamsForEventSoapEnvelope, HttpWebRequest getStreamsForEventWebRequest)
        {
            using (Stream stream = getStreamsForEventWebRequest.GetRequestStream())
            {
                getStreamsForEventSoapEnvelope.Save(stream);
            }
        }

This method creates the soap envelope

/// <summary>
        /// 
        /// </summary>
        /// <param name="streamsForEvent"></param>
        /// <returns></returns>
        private static XmlDocument CreateSoapEnvelopeProcess<T>(T streamsForEvent)
        {
            XmlDocument soapEnvelop = new XmlDocument();

            soapEnvelop.LoadXml(File.ReadAllText(string.Format(@"C:\{0}.xml", streamsForEvent.GetType().Name.Replace("DTO", ""))));

            return FillSoapEnvelop(soapEnvelop, streamsForEvent);
        }

This method does the actuall filling of the soap envelop. I used reflection to get the name of each property of the DTO file, then I do a GetElementsByTagName with the property's name and then I fill it with the property's value.

/// <summary>
    /// 
    /// </summary>
    /// <param name="getStreamsForEventSoapEnvelope"></param>
    /// <param name="streamsForEvent"></param>
    /// <returns></returns>
    private static XmlDocument FillSoapEnvelop<T>(XmlDocument getStreamsForEventSoapEnvelope, T streamsForEvent) 
    {
        foreach (PropertyInfo property in typeof (T).GetProperties())
        {
            getStreamsForEventSoapEnvelope.GetElementsByTagName(property.Name).Item(0).InnerText = GenericHelperMethods.GetPropertyValue(streamsForEvent, property);  
        }

        return getStreamsForEventSoapEnvelope;
    }

This method gets the value of the DTO's properties

/// <summary>
        /// 
        /// </summary>
        /// <param name="streamsForEvent"></param>
        /// <param name="property"></param>
        /// <returns></returns>
        public static string GetPropertyValue<T>(T streamsForEvent, PropertyInfo property)
        {
            return streamsForEvent.GetType().GetProperty(property.Name).GetValue(streamsForEvent, null).ToString();
        }

The problem occurrs at

private static XmlDocument FillSoapEnvelop<T>(XmlDocument getStreamsForEventSoapEnvelope, T streamsForEvent) 

The way I'm reading the xml must have some problem, because it works fine with with

 <soap:Envelope xmlns:soap="http://ift.tt/sVJIaE">
      <soap:Body>
        <GetStreamsForEvent xmlns="...">
          <customerUID></customerUID>
          <eventId></eventId>
        </GetStreamsForEvent>
      </soap:Body>
    </soap:Envelope>

but not with

<soap:Envelope xmlns:soap="http://ift.tt/sVJIaE">
  <soap:Body>
    <soap:Envelope xmlns:soap="http://ift.tt/sVJIaE">
  <soap:Body>
    <GenerateEventView xmlns="...">
      <igmStreamInput>
        <CustomerUID></CustomerUID>
...
        <RedirectURL></RedirectURL>
      </igmStreamInput>
    </GenerateEventView>
  </soap:Body>
</soap:Envelope>
  </soap:Body>
</soap:Envelope>

Any ideas? Tks in advance.





Aucun commentaire:

Enregistrer un commentaire