Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. How to handle multiple exceptions(Try..Catch)

How to handle multiple exceptions(Try..Catch)

Scheduled Pinned Locked Moved C#
sysadmindebuggingxmljsonhelp
26 Posts 3 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Bootzilla33
    wrote on last edited by
    #1

    I'm trying to figure out how to handle multiple exceptions based off my code. I want to have an error for API, one for Tracking Number, and then one for if the XML isn't formatted for the entire XML. Would using try catch for each be the best method and if so how would I code that. The code in bold is what I need assistance with in regards for Tracking Number and API Here is what I have currently:

    try
    {
    if (bool.Parse(WebConfigurationManager.AppSettings["Debug"]) == true)
    File.WriteAllText(Path.Combine(Server.MapPath("Log"), DateTime.Now.ToString("MMddyyy_HHmmss") + ".xml"), xmlRequest);
    // Determine Method to Call
    XmlDocument doc = new XmlDocument();
    doc.XmlResolver = null;
    doc.LoadXml(xmlRequest);

                string method = doc.FirstChild.Name;
                XmlNode mainNode = doc.FirstChild;
    
                if (method.ToLower() == "xml")
                {
                    method = doc.FirstChild.NextSibling.Name;
                    mainNode = doc.FirstChild.NextSibling;
                }
    
                if (method == "AmazonTrackingRequest")
                {
                    Data.General.Shipment prc = new Data.General.Shipment();
                    string pronum = mainNode.SelectSingleNode("TrackingNumber")?.InnerText;
                    prc.GetByProNumber(decimal.Parse(pronum));
    
                   
                                        
                    **rspxml.Root.Add(new XElement("API", "4.0"));
                    rspxml.Root.Add(new XElement("PackageTrackingInfo"));
                    rspxml.Root.Element("PackageTrackingInfo").Add(new XElement("TrackingNumber", prc.ProNumber.ToString()));**
                    rspxml.Root.Add(new XElement("PackageDestinationLocation"));
                    rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("City", prc.Consignee.ToString()));
                    rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("StateProvince", prc.Consignee.ToString()));
                    rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("PostalCode", prc.Consignee.ToString()));
                    rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("CountryCode", prc.Consignee.ToString()));
                    rspxml.Root.Add(new XElement("PackageDeliveryDate"));
                    rspxml.Root.Element("PackageDeliveryDate"
    
    Richard DeemingR E 2 Replies Last reply
    0
    • B Bootzilla33

      I'm trying to figure out how to handle multiple exceptions based off my code. I want to have an error for API, one for Tracking Number, and then one for if the XML isn't formatted for the entire XML. Would using try catch for each be the best method and if so how would I code that. The code in bold is what I need assistance with in regards for Tracking Number and API Here is what I have currently:

      try
      {
      if (bool.Parse(WebConfigurationManager.AppSettings["Debug"]) == true)
      File.WriteAllText(Path.Combine(Server.MapPath("Log"), DateTime.Now.ToString("MMddyyy_HHmmss") + ".xml"), xmlRequest);
      // Determine Method to Call
      XmlDocument doc = new XmlDocument();
      doc.XmlResolver = null;
      doc.LoadXml(xmlRequest);

                  string method = doc.FirstChild.Name;
                  XmlNode mainNode = doc.FirstChild;
      
                  if (method.ToLower() == "xml")
                  {
                      method = doc.FirstChild.NextSibling.Name;
                      mainNode = doc.FirstChild.NextSibling;
                  }
      
                  if (method == "AmazonTrackingRequest")
                  {
                      Data.General.Shipment prc = new Data.General.Shipment();
                      string pronum = mainNode.SelectSingleNode("TrackingNumber")?.InnerText;
                      prc.GetByProNumber(decimal.Parse(pronum));
      
                     
                                          
                      **rspxml.Root.Add(new XElement("API", "4.0"));
                      rspxml.Root.Add(new XElement("PackageTrackingInfo"));
                      rspxml.Root.Element("PackageTrackingInfo").Add(new XElement("TrackingNumber", prc.ProNumber.ToString()));**
                      rspxml.Root.Add(new XElement("PackageDestinationLocation"));
                      rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("City", prc.Consignee.ToString()));
                      rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("StateProvince", prc.Consignee.ToString()));
                      rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("PostalCode", prc.Consignee.ToString()));
                      rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("CountryCode", prc.Consignee.ToString()));
                      rspxml.Root.Add(new XElement("PackageDeliveryDate"));
                      rspxml.Root.Element("PackageDeliveryDate"
      
      Richard DeemingR Online
      Richard DeemingR Online
      Richard Deeming
      wrote on last edited by
      #2

      The code you're using to build the XML can be greatly simplified:

      rspxml.Root.Add(
      new XElement("API", "4.0"),
      new XElement("PackageTrackingInfo",
      new XElement("TrackingNumber", prc.ProNumber)
      ),
      new XElement("PackageDestinationLocation",
      new XElement("City", prc.Consignee),
      new XElement("StateProvince", prc.Consignee),
      new XElement("PostalCode", prc.Consignee),
      new XElement("CountryCode", prc.Consignee)
      ),
      new XElement("PackageDeliveryDate",
      new XElement("ScheduledDeliveryDate", prc.Consignee),
      new XElement("ReScheduledDeliveryDate", prc.Consignee)
      ),
      new XElement("TrackingEventHistory",
      prc.History.Select(item => new XElement("TrackingEventDetail",
      // TODO: Use the correct properties from the item, which weren't shown in your code:
      new XElement("EventStatus", item.EventStatus),
      new XElement("EventReason", item.EventReason),
      new XElement("EventDateTime", item.EventDateTime),
      new XElement("EventLocation", item.EventLocation)
      )
      )
      );

      This will also fix the problem you currently have where elements are appended to the wrong parent - particularly within the "history" loop. Now you just need to explain what the problem is, and why you're still mixing XmlDocument and XDocument documents. :)


      "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

      "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

      B 2 Replies Last reply
      0
      • Richard DeemingR Richard Deeming

        The code you're using to build the XML can be greatly simplified:

        rspxml.Root.Add(
        new XElement("API", "4.0"),
        new XElement("PackageTrackingInfo",
        new XElement("TrackingNumber", prc.ProNumber)
        ),
        new XElement("PackageDestinationLocation",
        new XElement("City", prc.Consignee),
        new XElement("StateProvince", prc.Consignee),
        new XElement("PostalCode", prc.Consignee),
        new XElement("CountryCode", prc.Consignee)
        ),
        new XElement("PackageDeliveryDate",
        new XElement("ScheduledDeliveryDate", prc.Consignee),
        new XElement("ReScheduledDeliveryDate", prc.Consignee)
        ),
        new XElement("TrackingEventHistory",
        prc.History.Select(item => new XElement("TrackingEventDetail",
        // TODO: Use the correct properties from the item, which weren't shown in your code:
        new XElement("EventStatus", item.EventStatus),
        new XElement("EventReason", item.EventReason),
        new XElement("EventDateTime", item.EventDateTime),
        new XElement("EventLocation", item.EventLocation)
        )
        )
        );

        This will also fix the problem you currently have where elements are appended to the wrong parent - particularly within the "history" loop. Now you just need to explain what the problem is, and why you're still mixing XmlDocument and XDocument documents. :)


        "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

        B Offline
        B Offline
        Bootzilla33
        wrote on last edited by
        #3

        The problem is, not really a problem, I have error codes for the Tracking Number and API Version XElement that I want to using exceptions like this:

        rspxml = XDocument.Parse("12345678ERROR_101INVALID TRACKING NUMBER");

        So for instance when there is an invalid Tracking Number I want the xml to read this error_101 code. As for XMLDocument and XDocument, what are your suggestions for those?

        Richard DeemingR 1 Reply Last reply
        0
        • B Bootzilla33

          The problem is, not really a problem, I have error codes for the Tracking Number and API Version XElement that I want to using exceptions like this:

          rspxml = XDocument.Parse("12345678ERROR_101INVALID TRACKING NUMBER");

          So for instance when there is an invalid Tracking Number I want the xml to read this error_101 code. As for XMLDocument and XDocument, what are your suggestions for those?

          Richard DeemingR Online
          Richard DeemingR Online
          Richard Deeming
          wrote on last edited by
          #4

          Firstly, that's not a valid XML document. You either need to remove the closing </AmazonTrackingResponse> tag, or insert the opening tag. Secondly, you would read it in the same way as any other XML document:

          var rspxml = XDocument.Parse("<?xml version=\"1.0\" encoding=\"UTF-8\"?><AmazonTrackingResponse><TrackingErrorInfo><TrackingNumber>12345678</TrackingNumber><TrackingErrorDetail><ErrorDetailCode>ERROR_101</ErrorDetailCode><ErrorDetailCodeDesc>INVALID TRACKING NUMBER</ErrorDetailCodeDesc></TrackingErrorDetail></TrackingErrorInfo></AmazonTrackingResponse>");

          var errorInfo = rspxml.Descendants("TrackingErrorInfo").FirstOrDefault();
          if (errorInfo != null)
          {
          string trackingNumber = (string)errorInfo.Element("TrackingNumber");

          var detail = errorInfo.Element("TrackingErrorDetail");
          if (detail != null)
          {
              string errorCode = (string)detail.Element("ErrorDetailCode");
              string errorMessage = (string)detail.Element("ErrorDetailCodeDesc");
              // Do something with the error details...
          }
          

          }

          As for the XmlDocument vs XDocument, I'd suggest choosing one and sticking to it. The XDocument is generally easier to work with.


          "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

          "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

          B 1 Reply Last reply
          0
          • Richard DeemingR Richard Deeming

            Firstly, that's not a valid XML document. You either need to remove the closing </AmazonTrackingResponse> tag, or insert the opening tag. Secondly, you would read it in the same way as any other XML document:

            var rspxml = XDocument.Parse("<?xml version=\"1.0\" encoding=\"UTF-8\"?><AmazonTrackingResponse><TrackingErrorInfo><TrackingNumber>12345678</TrackingNumber><TrackingErrorDetail><ErrorDetailCode>ERROR_101</ErrorDetailCode><ErrorDetailCodeDesc>INVALID TRACKING NUMBER</ErrorDetailCodeDesc></TrackingErrorDetail></TrackingErrorInfo></AmazonTrackingResponse>");

            var errorInfo = rspxml.Descendants("TrackingErrorInfo").FirstOrDefault();
            if (errorInfo != null)
            {
            string trackingNumber = (string)errorInfo.Element("TrackingNumber");

            var detail = errorInfo.Element("TrackingErrorDetail");
            if (detail != null)
            {
                string errorCode = (string)detail.Element("ErrorDetailCode");
                string errorMessage = (string)detail.Element("ErrorDetailCodeDesc");
                // Do something with the error details...
            }
            

            }

            As for the XmlDocument vs XDocument, I'd suggest choosing one and sticking to it. The XDocument is generally easier to work with.


            "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

            B Offline
            B Offline
            Bootzilla33
            wrote on last edited by
            #5

            Yeah I just post part of that tag. I didn't want to post the entire thing so that's why the beginning tag isn't showing here. Also how would I check for errors on

            rspxml.Root.Add(new XElement("APIVersion", "4.0"));

            and I have an error code for if 'XML is not well formed', how would I do that one. And thanks on using one between XMLDocument or XDocument.

            1 Reply Last reply
            0
            • B Bootzilla33

              I'm trying to figure out how to handle multiple exceptions based off my code. I want to have an error for API, one for Tracking Number, and then one for if the XML isn't formatted for the entire XML. Would using try catch for each be the best method and if so how would I code that. The code in bold is what I need assistance with in regards for Tracking Number and API Here is what I have currently:

              try
              {
              if (bool.Parse(WebConfigurationManager.AppSettings["Debug"]) == true)
              File.WriteAllText(Path.Combine(Server.MapPath("Log"), DateTime.Now.ToString("MMddyyy_HHmmss") + ".xml"), xmlRequest);
              // Determine Method to Call
              XmlDocument doc = new XmlDocument();
              doc.XmlResolver = null;
              doc.LoadXml(xmlRequest);

                          string method = doc.FirstChild.Name;
                          XmlNode mainNode = doc.FirstChild;
              
                          if (method.ToLower() == "xml")
                          {
                              method = doc.FirstChild.NextSibling.Name;
                              mainNode = doc.FirstChild.NextSibling;
                          }
              
                          if (method == "AmazonTrackingRequest")
                          {
                              Data.General.Shipment prc = new Data.General.Shipment();
                              string pronum = mainNode.SelectSingleNode("TrackingNumber")?.InnerText;
                              prc.GetByProNumber(decimal.Parse(pronum));
              
                             
                                                  
                              **rspxml.Root.Add(new XElement("API", "4.0"));
                              rspxml.Root.Add(new XElement("PackageTrackingInfo"));
                              rspxml.Root.Element("PackageTrackingInfo").Add(new XElement("TrackingNumber", prc.ProNumber.ToString()));**
                              rspxml.Root.Add(new XElement("PackageDestinationLocation"));
                              rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("City", prc.Consignee.ToString()));
                              rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("StateProvince", prc.Consignee.ToString()));
                              rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("PostalCode", prc.Consignee.ToString()));
                              rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("CountryCode", prc.Consignee.ToString()));
                              rspxml.Root.Add(new XElement("PackageDeliveryDate"));
                              rspxml.Root.Element("PackageDeliveryDate"
              
              E Offline
              E Offline
              eddieangel
              wrote on last edited by
              #6

              The old adage Exceptions should be Exceptional applies here. Rather than using multiple try ... catch blocks, my advice is to validate your known inputs up front. While I personally find it ugly to use a series of If (!x) { return; } it is a solid method of keeping your code simple and implicit. I am not sure what the bold issue is because you are using static values so I don't know what you would catch there. Starting at the third element, though, I would advocate writing a validator of some sort to validate the Shipment object. And to possibly save you some grief, might I suggest cutting out some of the craziness and just using a serializer to serialize the shipment object? IT can save you a TON of grief trying to validate the XML> If you can't serialize the Shipment directly because of schema differences, try creating a DTO that matches the XML you want and serializing that. Working with raw XML like this should be a last resort. That is my 2c

              B 1 Reply Last reply
              0
              • E eddieangel

                The old adage Exceptions should be Exceptional applies here. Rather than using multiple try ... catch blocks, my advice is to validate your known inputs up front. While I personally find it ugly to use a series of If (!x) { return; } it is a solid method of keeping your code simple and implicit. I am not sure what the bold issue is because you are using static values so I don't know what you would catch there. Starting at the third element, though, I would advocate writing a validator of some sort to validate the Shipment object. And to possibly save you some grief, might I suggest cutting out some of the craziness and just using a serializer to serialize the shipment object? IT can save you a TON of grief trying to validate the XML> If you can't serialize the Shipment directly because of schema differences, try creating a DTO that matches the XML you want and serializing that. Working with raw XML like this should be a last resort. That is my 2c

                B Offline
                B Offline
                Bootzilla33
                wrote on last edited by
                #7

                @eddieangel, how would you code what I'm trying to do with API Version, Tracking Number using If (!x) {return}?

                E 1 Reply Last reply
                0
                • B Bootzilla33

                  @eddieangel, how would you code what I'm trying to do with API Version, Tracking Number using If (!x) {return}?

                  E Offline
                  E Offline
                  eddieangel
                  wrote on last edited by
                  #8

                  I am not sure what the validation looks like for your situation, but there are a couple of methods. The most simple is to validate to see if the string exists.

                  if (string.isNullOrEmpty(apiVariableName)) { return ; }

                  Since the first two bold items are static text there really isn't anything to validate there unless there is something else we aren't seeing. That said, one of the best methods to validate your data is to set validation attributes on your model class (Data.General.Shipment() and write a method that validates that. For example:

                  internal class Shipment {
                  [Required]
                  [StringLength(12)]
                  public string ShippingNumber { get; set; }

                      \[Required(ErrorMessage = "City cannot be empty.")\]
                      public string City { get; set; }
                  
                      \[Required(ErrorMessage = "Zip is Required")\]
                      \[RegularExpression(@"^\\d{5}(-\\d{4})?$", ErrorMessage = "Invalid Zip")\]
                      public string PostalCode { get; set; }
                  }
                  

                  The trick here is that you really want to leave your model validating to the model or validator class and not be trying to validate when you are building the XML. It is good defensive programming to cover null possibilities and such, but you really want to uncomplicate things as much as possible if you are crafting an XML by hand.

                  B 1 Reply Last reply
                  0
                  • E eddieangel

                    I am not sure what the validation looks like for your situation, but there are a couple of methods. The most simple is to validate to see if the string exists.

                    if (string.isNullOrEmpty(apiVariableName)) { return ; }

                    Since the first two bold items are static text there really isn't anything to validate there unless there is something else we aren't seeing. That said, one of the best methods to validate your data is to set validation attributes on your model class (Data.General.Shipment() and write a method that validates that. For example:

                    internal class Shipment {
                    [Required]
                    [StringLength(12)]
                    public string ShippingNumber { get; set; }

                        \[Required(ErrorMessage = "City cannot be empty.")\]
                        public string City { get; set; }
                    
                        \[Required(ErrorMessage = "Zip is Required")\]
                        \[RegularExpression(@"^\\d{5}(-\\d{4})?$", ErrorMessage = "Invalid Zip")\]
                        public string PostalCode { get; set; }
                    }
                    

                    The trick here is that you really want to leave your model validating to the model or validator class and not be trying to validate when you are building the XML. It is good defensive programming to cover null possibilities and such, but you really want to uncomplicate things as much as possible if you are crafting an XML by hand.

                    B Offline
                    B Offline
                    Bootzilla33
                    wrote on last edited by
                    #9

                    So where would the model class go in relation to my code. Would it be outside of the XElement code? Before it? After it?

                    E 1 Reply Last reply
                    0
                    • B Bootzilla33

                      So where would the model class go in relation to my code. Would it be outside of the XElement code? Before it? After it?

                      E Offline
                      E Offline
                      eddieangel
                      wrote on last edited by
                      #10

                      Your model class already exists, it is the Data.General.Shipment object. All of this is really outside the scope of your original question of multiple try... catch... blocks, though. If you are able it is always good to step back and ask yourself if this is the right approach. DO you really need XML? It is super wordy and a pain to work with, JSON is way better, but again, outside the scope. To put an easy stamp on your original question, you can have many try catch blocks but it is going to be a very iterative process for you to figure them out and consider all of the permutations. So you have to ask yourself what the goal is. Is there a recovery path through these exceptions or are you trying to send different error messages to the user? Or maybe just log more detail? Either way if your try/catch is at the point of building out the XML all you are likely to get is XML formatting exceptions, which do not encapsulate your business rules. A couple notes on generally being defensive in the code you have written: 1. Do not use decimal.Parse. Since you are using the null check operator getting the tracking number, you expose the possibility of errors there. Try this:

                      var prc = new Data.General.Shipment();
                      var node = mainNode.SelectSingleNode("TrackingNumber");

                                      if (node == null)
                                      {
                                          return; // If your method is not void return the appropriate data type, null, false, etc...
                                      }
                      
                                      decimal trackingNumber;
                      
                                      if (!decimal.TryParse(node.InnertText, out trackingNumber))
                                      {
                                          return; // Same as above with return type
                                      }
                      
                                      prc.GetByProNumber(trackingNumber);
                      
                                      try
                                      {
                                          rspxml.Root.Add(new XElement("API", "4.0"));
                                          rspxml.Root.Add(new XElement("PackageTrackingInfo"));
                                          rspxml.Root.Element("PackageTrackingInfo").Add(new XElement("TrackingNumber", prc.ProNumber.ToString())); // These ToString calls are dangerous without first validating the data
                                          rspxml.Root.Add(new XElement("PackageDestinationLocation"));
                                          rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("City", prc.Consignee.ToString()));
                                          rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("StateProvince", prc.
                      
                      B 1 Reply Last reply
                      0
                      • E eddieangel

                        Your model class already exists, it is the Data.General.Shipment object. All of this is really outside the scope of your original question of multiple try... catch... blocks, though. If you are able it is always good to step back and ask yourself if this is the right approach. DO you really need XML? It is super wordy and a pain to work with, JSON is way better, but again, outside the scope. To put an easy stamp on your original question, you can have many try catch blocks but it is going to be a very iterative process for you to figure them out and consider all of the permutations. So you have to ask yourself what the goal is. Is there a recovery path through these exceptions or are you trying to send different error messages to the user? Or maybe just log more detail? Either way if your try/catch is at the point of building out the XML all you are likely to get is XML formatting exceptions, which do not encapsulate your business rules. A couple notes on generally being defensive in the code you have written: 1. Do not use decimal.Parse. Since you are using the null check operator getting the tracking number, you expose the possibility of errors there. Try this:

                        var prc = new Data.General.Shipment();
                        var node = mainNode.SelectSingleNode("TrackingNumber");

                                        if (node == null)
                                        {
                                            return; // If your method is not void return the appropriate data type, null, false, etc...
                                        }
                        
                                        decimal trackingNumber;
                        
                                        if (!decimal.TryParse(node.InnertText, out trackingNumber))
                                        {
                                            return; // Same as above with return type
                                        }
                        
                                        prc.GetByProNumber(trackingNumber);
                        
                                        try
                                        {
                                            rspxml.Root.Add(new XElement("API", "4.0"));
                                            rspxml.Root.Add(new XElement("PackageTrackingInfo"));
                                            rspxml.Root.Element("PackageTrackingInfo").Add(new XElement("TrackingNumber", prc.ProNumber.ToString())); // These ToString calls are dangerous without first validating the data
                                            rspxml.Root.Add(new XElement("PackageDestinationLocation"));
                                            rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("City", prc.Consignee.ToString()));
                                            rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("StateProvince", prc.
                        
                        B Offline
                        B Offline
                        Bootzilla33
                        wrote on last edited by
                        #11

                        I am using XML because I'm outputting it to AWS. So I don't have a choice unfortunately.

                        1 Reply Last reply
                        0
                        • Richard DeemingR Richard Deeming

                          The code you're using to build the XML can be greatly simplified:

                          rspxml.Root.Add(
                          new XElement("API", "4.0"),
                          new XElement("PackageTrackingInfo",
                          new XElement("TrackingNumber", prc.ProNumber)
                          ),
                          new XElement("PackageDestinationLocation",
                          new XElement("City", prc.Consignee),
                          new XElement("StateProvince", prc.Consignee),
                          new XElement("PostalCode", prc.Consignee),
                          new XElement("CountryCode", prc.Consignee)
                          ),
                          new XElement("PackageDeliveryDate",
                          new XElement("ScheduledDeliveryDate", prc.Consignee),
                          new XElement("ReScheduledDeliveryDate", prc.Consignee)
                          ),
                          new XElement("TrackingEventHistory",
                          prc.History.Select(item => new XElement("TrackingEventDetail",
                          // TODO: Use the correct properties from the item, which weren't shown in your code:
                          new XElement("EventStatus", item.EventStatus),
                          new XElement("EventReason", item.EventReason),
                          new XElement("EventDateTime", item.EventDateTime),
                          new XElement("EventLocation", item.EventLocation)
                          )
                          )
                          );

                          This will also fix the problem you currently have where elements are appended to the wrong parent - particularly within the "history" loop. Now you just need to explain what the problem is, and why you're still mixing XmlDocument and XDocument documents. :)


                          "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                          B Offline
                          B Offline
                          Bootzilla33
                          wrote on last edited by
                          #12

                          rspxml.Root.Add(
                          new XElement("API", "4.0"),
                          new XElement("PackageTrackingInfo",
                          new XElement("TrackingNumber", prc.ProNumber)
                          ),
                          new XElement("PackageDestinationLocation",
                          new XElement("City", prc.Consignee),
                          new XElement("StateProvince", prc.Consignee),
                          new XElement("PostalCode", prc.Consignee),
                          new XElement("CountryCode", prc.Consignee)
                          ),
                          new XElement("PackageDeliveryDate",
                          new XElement("ScheduledDeliveryDate", prc.Consignee),
                          new XElement("ReScheduledDeliveryDate", prc.Consignee)
                          ),
                          new XElement("TrackingEventHistory",
                          prc.History.Select(item => new XElement("TrackingEventDetail",
                          // TODO: Use the correct properties from the item, which weren't shown in your code:
                          new XElement("EventStatus", item.EventStatus),
                          new XElement("EventReason", item.EventReason),
                          new XElement("EventDateTime", item.EventDateTime),
                          new XElement("EventLocation", item.EventLocation)
                          )
                          )
                          );

                          @RichardDeeming, Question about this code. On the

                          new XElement("TrackingEventHistory",
                          prc.History.Select(item => new XElement("TrackingEventDetail",

                          line what should that be because you have .Select but that gives me an error 'Shipment.HistoryCollection' does not contain a definition for 'Select' and no extension method 'Select' accepting a first argument of type 'Shipment.HistoryCollection' could be found (are you missing a using directive or an assembly reference?) Is that code I should use and need to add something to eliminate the error. What I was thinking it should be is:

                          new XElement("TrackingEventHistory",
                          new XElement("TrackingEventDetail",
                          // TODO: Use the correct properties from the item, which weren't shown in your code:
                          new XElement("EventStatus", prc.History),
                          new XElement("EventReason", prc.History),
                          new XElement("EventDateTime", prc.History),
                          new XElement("EventLocation", prc.History)

                          E 1 Reply Last reply
                          0
                          • B Bootzilla33

                            rspxml.Root.Add(
                            new XElement("API", "4.0"),
                            new XElement("PackageTrackingInfo",
                            new XElement("TrackingNumber", prc.ProNumber)
                            ),
                            new XElement("PackageDestinationLocation",
                            new XElement("City", prc.Consignee),
                            new XElement("StateProvince", prc.Consignee),
                            new XElement("PostalCode", prc.Consignee),
                            new XElement("CountryCode", prc.Consignee)
                            ),
                            new XElement("PackageDeliveryDate",
                            new XElement("ScheduledDeliveryDate", prc.Consignee),
                            new XElement("ReScheduledDeliveryDate", prc.Consignee)
                            ),
                            new XElement("TrackingEventHistory",
                            prc.History.Select(item => new XElement("TrackingEventDetail",
                            // TODO: Use the correct properties from the item, which weren't shown in your code:
                            new XElement("EventStatus", item.EventStatus),
                            new XElement("EventReason", item.EventReason),
                            new XElement("EventDateTime", item.EventDateTime),
                            new XElement("EventLocation", item.EventLocation)
                            )
                            )
                            );

                            @RichardDeeming, Question about this code. On the

                            new XElement("TrackingEventHistory",
                            prc.History.Select(item => new XElement("TrackingEventDetail",

                            line what should that be because you have .Select but that gives me an error 'Shipment.HistoryCollection' does not contain a definition for 'Select' and no extension method 'Select' accepting a first argument of type 'Shipment.HistoryCollection' could be found (are you missing a using directive or an assembly reference?) Is that code I should use and need to add something to eliminate the error. What I was thinking it should be is:

                            new XElement("TrackingEventHistory",
                            new XElement("TrackingEventDetail",
                            // TODO: Use the correct properties from the item, which weren't shown in your code:
                            new XElement("EventStatus", prc.History),
                            new XElement("EventReason", prc.History),
                            new XElement("EventDateTime", prc.History),
                            new XElement("EventLocation", prc.History)

                            E Offline
                            E Offline
                            eddieangel
                            wrote on last edited by
                            #13

                            Select is a Linq statement. Try adding the proper using statement to the top of your class. using System.Linq; using System.Xml.Linq; If those do not work you may need to cast your object to something else.

                            B 1 Reply Last reply
                            0
                            • E eddieangel

                              Select is a Linq statement. Try adding the proper using statement to the top of your class. using System.Linq; using System.Xml.Linq; If those do not work you may need to cast your object to something else.

                              B Offline
                              B Offline
                              Bootzilla33
                              wrote on last edited by
                              #14

                              I already have these using System.Linq; using System.Xml.Linq; You mentioned Cast to something else but not sure what to do there. Anyone else with any suggestions would be appreciated.If no one has any suggestions then I will have to go back to the ToString code I had previously and just go with that. This is what I have now:

                              public string ProcessXML(string xmlRequest)
                              {
                              XDocument rspxml = null;
                              try
                              {
                              if (bool.Parse(WebConfigurationManager.AppSettings["Debug"]) == true)
                              File.WriteAllText(Path.Combine(Server.MapPath("Log"), DateTime.Now.ToString("MMddyyy_HHmmss") + ".xml"), xmlRequest);
                              // Determine Method to Call
                              XmlDocument doc = new XmlDocument();
                              doc.XmlResolver = null;
                              doc.LoadXml(xmlRequest);

                                          string method = doc.FirstChild.Name;
                                          XmlNode mainNode = doc.FirstChild;
                              
                                          if (method.ToLower() == "xml")
                                          {
                                              method = doc.FirstChild.NextSibling.Name;
                                              mainNode = doc.FirstChild.NextSibling;
                                          }
                              
                                          if (method == "AmazonTrackingRequest")
                                          {
                                              Saia.Data.General.Shipment prc = new Data.General.Shipment();
                                              string pronum = mainNode.SelectSingleNode("TrackingNumber").InnerText;
                                              prc.GetByProNumber(decimal.Parse(pronum));
                              
                                              if (string.IsNullOrEmpty(pronum))
                                              {
                                                  rspxml = XDocument.Parse("4.012345678ERROR\_101INVALID TRACKING NUMBER");
                                              }
                                              else
                                              {
                                                  decimal tn = 0.0m;
                              
                                                  if (decimal.TryParse(pronum, out tn))
                              
                                                  {
                                                      prc.GetByProNumber(tn);
                                                  }
                                                  else
                                                  {
                                                      Console.WriteLine("Unable to parse '{0}'.", pronum);
                              
                              Richard DeemingR 1 Reply Last reply
                              0
                              • B Bootzilla33

                                I already have these using System.Linq; using System.Xml.Linq; You mentioned Cast to something else but not sure what to do there. Anyone else with any suggestions would be appreciated.If no one has any suggestions then I will have to go back to the ToString code I had previously and just go with that. This is what I have now:

                                public string ProcessXML(string xmlRequest)
                                {
                                XDocument rspxml = null;
                                try
                                {
                                if (bool.Parse(WebConfigurationManager.AppSettings["Debug"]) == true)
                                File.WriteAllText(Path.Combine(Server.MapPath("Log"), DateTime.Now.ToString("MMddyyy_HHmmss") + ".xml"), xmlRequest);
                                // Determine Method to Call
                                XmlDocument doc = new XmlDocument();
                                doc.XmlResolver = null;
                                doc.LoadXml(xmlRequest);

                                            string method = doc.FirstChild.Name;
                                            XmlNode mainNode = doc.FirstChild;
                                
                                            if (method.ToLower() == "xml")
                                            {
                                                method = doc.FirstChild.NextSibling.Name;
                                                mainNode = doc.FirstChild.NextSibling;
                                            }
                                
                                            if (method == "AmazonTrackingRequest")
                                            {
                                                Saia.Data.General.Shipment prc = new Data.General.Shipment();
                                                string pronum = mainNode.SelectSingleNode("TrackingNumber").InnerText;
                                                prc.GetByProNumber(decimal.Parse(pronum));
                                
                                                if (string.IsNullOrEmpty(pronum))
                                                {
                                                    rspxml = XDocument.Parse("4.012345678ERROR\_101INVALID TRACKING NUMBER");
                                                }
                                                else
                                                {
                                                    decimal tn = 0.0m;
                                
                                                    if (decimal.TryParse(pronum, out tn))
                                
                                                    {
                                                        prc.GetByProNumber(tn);
                                                    }
                                                    else
                                                    {
                                                        Console.WriteLine("Unable to parse '{0}'.", pronum);
                                
                                Richard DeemingR Online
                                Richard DeemingR Online
                                Richard Deeming
                                wrote on last edited by
                                #15

                                What interfaces are implemented by Shipment.HistoryCollection? Presumably it implements IEnumerable, but not IEnumerable<T>; in which case, you need to insert a call to Cast[^] before the call to Select:

                                new XElement("TrackingEventHistory",
                                prc.History.Cast<Saia.Data.General.Shipment.HistoryItem>().Select(item => new XElement("TrackingEventDetail",
                                // TODO: Use the correct properties from the item, which weren't shown in your code:
                                new XElement("EventStatus", item.EventStatus),
                                new XElement("EventReason", item.EventReason),
                                new XElement("EventDateTime", item.EventDateTime),
                                new XElement("EventLocation", item.EventLocation)
                                )
                                )


                                "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                                "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                                B 1 Reply Last reply
                                0
                                • Richard DeemingR Richard Deeming

                                  What interfaces are implemented by Shipment.HistoryCollection? Presumably it implements IEnumerable, but not IEnumerable<T>; in which case, you need to insert a call to Cast[^] before the call to Select:

                                  new XElement("TrackingEventHistory",
                                  prc.History.Cast<Saia.Data.General.Shipment.HistoryItem>().Select(item => new XElement("TrackingEventDetail",
                                  // TODO: Use the correct properties from the item, which weren't shown in your code:
                                  new XElement("EventStatus", item.EventStatus),
                                  new XElement("EventReason", item.EventReason),
                                  new XElement("EventDateTime", item.EventDateTime),
                                  new XElement("EventLocation", item.EventLocation)
                                  )
                                  )


                                  "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                                  B Offline
                                  B Offline
                                  Bootzilla33
                                  wrote on last edited by
                                  #16

                                  OK this is what I have now and it seems to be working. A couple of questions/issues: 1. If you look at the commented out code below with the .ToString, I have PickupStoreInfo and then PickupDueDateDetails which is setup similar to the TrackingEventHistory and TrackingEventDetail, so would that be set up the same way with the Cast or should that be setup differently or is it ok like it is now.

                                  rspxml.Root.Add(new XElement("PickupStoreInfo"));
                                  // rspxml.Root.Add(new XElement("PickupDueDateDetails"));
                                  // rspxml.Root.Element("PickupDueDateDetails").Add(new XElement("Date", prc.History.ToString()));
                                  // rspxml.Root.Element("PickupDueDateDetails").Add(new XElement("UTCOffset", prc.History.ToString()));

                                  2. You mentioned about using one of either XDocument or XmlDocument, I tried this and when I change to XDocument on this line:

                                  XmlDocument doc = new XmlDocument();

                                  I get errors 'XDocument' does not contain a definition for 'XmlResolver' and no extension method 'XmlResolver' accepting a first argument of type 'XDocument' could be found (are you missing a using directive or an assembly reference?). Same error definition for FirstChild, LoadXML. If I change everything to XmlDocument like on this line from XDocument to XmlDocument:

                                  rspxml = XDocument.Parse

                                  I get 'XmlDocument does not contain definition for 'Parse'. 3.Is all of my syntax correct, specifically all of the parentheses after this line:

                                  new XElement("CountryCode", prc.History)

                                  I really appreciate all of your help and look forward to your response. Here is the full code for this method:

                                  public string ProcessXML(string xmlRequest)
                                  {
                                  XDocument rspxml = null;
                                  try
                                  {
                                  if (bool.Parse(WebConfigurationManager.AppSettings["Debug"]) == true)
                                  File.WriteAllText(Path.Combine(Server.MapPath("Log"), DateTime.Now.ToString("MMddyyy_HHmmss") + ".xml"), xmlRequest);
                                  // Determine Method to Call
                                  XmlDocument doc = new XmlDocument();
                                  doc.XmlResolver = null;
                                  doc.LoadXml(xmlRequest);

                                              string method = doc.FirstChild.Name;
                                              XmlNode mainNode = doc.FirstChild;
                                  
                                              if (method.ToLower() == "xml")
                                              {
                                                  method = doc.FirstChild.NextSibling.Name;
                                  
                                  Richard DeemingR 1 Reply Last reply
                                  0
                                  • B Bootzilla33

                                    OK this is what I have now and it seems to be working. A couple of questions/issues: 1. If you look at the commented out code below with the .ToString, I have PickupStoreInfo and then PickupDueDateDetails which is setup similar to the TrackingEventHistory and TrackingEventDetail, so would that be set up the same way with the Cast or should that be setup differently or is it ok like it is now.

                                    rspxml.Root.Add(new XElement("PickupStoreInfo"));
                                    // rspxml.Root.Add(new XElement("PickupDueDateDetails"));
                                    // rspxml.Root.Element("PickupDueDateDetails").Add(new XElement("Date", prc.History.ToString()));
                                    // rspxml.Root.Element("PickupDueDateDetails").Add(new XElement("UTCOffset", prc.History.ToString()));

                                    2. You mentioned about using one of either XDocument or XmlDocument, I tried this and when I change to XDocument on this line:

                                    XmlDocument doc = new XmlDocument();

                                    I get errors 'XDocument' does not contain a definition for 'XmlResolver' and no extension method 'XmlResolver' accepting a first argument of type 'XDocument' could be found (are you missing a using directive or an assembly reference?). Same error definition for FirstChild, LoadXML. If I change everything to XmlDocument like on this line from XDocument to XmlDocument:

                                    rspxml = XDocument.Parse

                                    I get 'XmlDocument does not contain definition for 'Parse'. 3.Is all of my syntax correct, specifically all of the parentheses after this line:

                                    new XElement("CountryCode", prc.History)

                                    I really appreciate all of your help and look forward to your response. Here is the full code for this method:

                                    public string ProcessXML(string xmlRequest)
                                    {
                                    XDocument rspxml = null;
                                    try
                                    {
                                    if (bool.Parse(WebConfigurationManager.AppSettings["Debug"]) == true)
                                    File.WriteAllText(Path.Combine(Server.MapPath("Log"), DateTime.Now.ToString("MMddyyy_HHmmss") + ".xml"), xmlRequest);
                                    // Determine Method to Call
                                    XmlDocument doc = new XmlDocument();
                                    doc.XmlResolver = null;
                                    doc.LoadXml(xmlRequest);

                                                string method = doc.FirstChild.Name;
                                                XmlNode mainNode = doc.FirstChild;
                                    
                                                if (method.ToLower() == "xml")
                                                {
                                                    method = doc.FirstChild.NextSibling.Name;
                                    
                                    Richard DeemingR Online
                                    Richard DeemingR Online
                                    Richard Deeming
                                    wrote on last edited by
                                    #17

                                    1) It's not clear what you're trying to do here. You're not adding an element for each history item, so you don't need the Select; you just need to pass in the correct values to the elements.

                                    rspxml.Root.Add(new XElement("PickupDueDateDetails"),
                                    new XElement("Date", prc.PickupDueDate),
                                    new XElement("UTCOffset", prc.PickupDueDateOffset)
                                    );

                                    2) You can't just change the type and expect the existing code to work. You need to fix the existing code to use the correct methods for the type. For example, this:

                                    XmlDocument doc = new XmlDocument();
                                    doc.XmlResolver = null;
                                    doc.LoadXml(xmlRequest);

                                    would become:

                                    XDocument doc = XDocument.Parse(xmlResult);

                                    This:

                                    string method = doc.FirstChild.Name;
                                    XmlNode mainNode = doc.FirstChild;

                                    if (method.ToLower() == "xml")
                                    {
                                    method = doc.FirstChild.NextSibling.Name;
                                    mainNode = doc.FirstChild.NextSibling;
                                    }

                                    would become:

                                    XElement mainNode = doc.Root;
                                    string method = mainNode.Name.LocalName;
                                    // No need to check for the processing instruction here...

                                    This:

                                    string pronum = mainNode.SelectSingleNode("TrackingNumber").InnerText;

                                    would become:

                                    string pronum = (string)mainNode.Element("TrackingNumber");

                                    3) I don't know. Does it compile? Does it do what you expect it to do? I very much doubt that prc.History is the correct property to use for all of those elements.


                                    "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                                    "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                                    B 1 Reply Last reply
                                    0
                                    • Richard DeemingR Richard Deeming

                                      1) It's not clear what you're trying to do here. You're not adding an element for each history item, so you don't need the Select; you just need to pass in the correct values to the elements.

                                      rspxml.Root.Add(new XElement("PickupDueDateDetails"),
                                      new XElement("Date", prc.PickupDueDate),
                                      new XElement("UTCOffset", prc.PickupDueDateOffset)
                                      );

                                      2) You can't just change the type and expect the existing code to work. You need to fix the existing code to use the correct methods for the type. For example, this:

                                      XmlDocument doc = new XmlDocument();
                                      doc.XmlResolver = null;
                                      doc.LoadXml(xmlRequest);

                                      would become:

                                      XDocument doc = XDocument.Parse(xmlResult);

                                      This:

                                      string method = doc.FirstChild.Name;
                                      XmlNode mainNode = doc.FirstChild;

                                      if (method.ToLower() == "xml")
                                      {
                                      method = doc.FirstChild.NextSibling.Name;
                                      mainNode = doc.FirstChild.NextSibling;
                                      }

                                      would become:

                                      XElement mainNode = doc.Root;
                                      string method = mainNode.Name.LocalName;
                                      // No need to check for the processing instruction here...

                                      This:

                                      string pronum = mainNode.SelectSingleNode("TrackingNumber").InnerText;

                                      would become:

                                      string pronum = (string)mainNode.Element("TrackingNumber");

                                      3) I don't know. Does it compile? Does it do what you expect it to do? I very much doubt that prc.History is the correct property to use for all of those elements.


                                      "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                                      B Offline
                                      B Offline
                                      Bootzilla33
                                      wrote on last edited by
                                      #18
                                      1. This may help explain. This is some of the XML I am trying to write out:

                                      LK
                                      AQ
                                      2004-08-22T11:00:00-
                                      08:00
                                      SEATTLE
                                      WA
                                      98107
                                      US
                                      JOHN GALT

                                      2004-08-25
                                      -07:00
                                      92253
                                      US-PRI-DEL-03
                                      19632
                                      NW Market St
                                      SEATTLE
                                      WA
                                      98107
                                      US

                                      Am I doing a rspxml.Root.Add for each section or can I use like this:

                                      new XElement("PickupStoreInfo",
                                      new XElement("PickupDueDateDetails",
                                      new XElement("Date", prc.History),
                                      new XElement("UTCOffset", prc.History)
                                      ),

                                      So based off this, how would that be written out in the code. 2) I updated the code and that seems to be working ok. 3) It does compile. And yes those are supposed to be prc.History. There are only two elements/fields that I'm concerned with and that is the Consignee and History so yes they should be prc.History. I just need to pull in the fields for in those two areas.

                                      Richard DeemingR 1 Reply Last reply
                                      0
                                      • B Bootzilla33
                                        1. This may help explain. This is some of the XML I am trying to write out:

                                        LK
                                        AQ
                                        2004-08-22T11:00:00-
                                        08:00
                                        SEATTLE
                                        WA
                                        98107
                                        US
                                        JOHN GALT

                                        2004-08-25
                                        -07:00
                                        92253
                                        US-PRI-DEL-03
                                        19632
                                        NW Market St
                                        SEATTLE
                                        WA
                                        98107
                                        US

                                        Am I doing a rspxml.Root.Add for each section or can I use like this:

                                        new XElement("PickupStoreInfo",
                                        new XElement("PickupDueDateDetails",
                                        new XElement("Date", prc.History),
                                        new XElement("UTCOffset", prc.History)
                                        ),

                                        So based off this, how would that be written out in the code. 2) I updated the code and that seems to be working ok. 3) It does compile. And yes those are supposed to be prc.History. There are only two elements/fields that I'm concerned with and that is the Consignee and History so yes they should be prc.History. I just need to pull in the fields for in those two areas.

                                        Richard DeemingR Online
                                        Richard DeemingR Online
                                        Richard Deeming
                                        wrote on last edited by
                                        #19

                                        Bootzilla33 wrote:

                                        new XElement("PickupStoreInfo",
                                        new XElement("PickupDueDateDetails",
                                        new XElement("Date", prc.History),
                                        new XElement("UTCOffset", prc.History)
                                        ),

                                        Since PickupDueDateDetails is a child of PickupStoreInfo, that's the correct way to do it. But passing prc.History as the value for every node isn't going to produce the correct values in the resulting XML. Instead, you'll get the result of calling prc.History.ToString() inserted into every node. If you don't need to pass a value in the node, it would be better to not pass a value to it, or exclude it from the document.


                                        "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                                        "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                                        B 1 Reply Last reply
                                        0
                                        • Richard DeemingR Richard Deeming

                                          Bootzilla33 wrote:

                                          new XElement("PickupStoreInfo",
                                          new XElement("PickupDueDateDetails",
                                          new XElement("Date", prc.History),
                                          new XElement("UTCOffset", prc.History)
                                          ),

                                          Since PickupDueDateDetails is a child of PickupStoreInfo, that's the correct way to do it. But passing prc.History as the value for every node isn't going to produce the correct values in the resulting XML. Instead, you'll get the result of calling prc.History.ToString() inserted into every node. If you don't need to pass a value in the node, it would be better to not pass a value to it, or exclude it from the document.


                                          "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                                          B Offline
                                          B Offline
                                          Bootzilla33
                                          wrote on last edited by
                                          #20

                                          I have the same thing for prc.Consignee. So what would you suggest something like this:

                                          ),
                                          new XElement("PickupStoreInfo",
                                          new XElement("PickupDueDateDetails",
                                          new XElement("Date"),
                                          new XElement("UTCOffset")
                                          ),

                                          I pretty much have to pass a value in the node or else how else would I get the values?

                                          Richard DeemingR 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups