Please suggest how I can improve my code (like memory leakage, which pattern to use etc.). I have to parse a book XML in two ways: first from an FTP file and second from the REST API. I implemented the methods in one class.
public void GetBooksFromApi(int bookId, int bookNumber = 0)
{
string ApiBookIDPrefix = ConfigurationManager.AppSettings["ApiBookIDPrefix"].ToString();
string key = ConfigurationManager.AppSettings["BookApiKey"].ToString();
string apiBookIdValue = $"{ApiBookIDPrefix}{bookId}";
string restApiBookUrl = $"{ApiDownloadUrl}?BookID={apiBookIdValue}&key={key}&bookNumber={bookNumber}&limit=1";
string bookName = String.Empty;
string clientFolderPath = String.Empty;
string bookContent = String.Empty;
try
{//here to get response, parse xml and creating files process
using (Stream xmlResponseStream = GetRestApiResponse(restApiBookUrl))
{
IEnumerable<XElement> xmlRecords = ParseBookXml(xmlResponseStream);
if (xmlRecords == null)
throw new NullReferenceException($"No Book found to parse from rest api xml");
foreach (var xmlRecord in xmlRecords)
{
if (xmlRecord.Element("BookError") == null)
{
bookName = GetBookName(xmlRecord, bookId);
clientFolderPath = $@"{BaseFolder}\{bookId}";
bookContent = xmlRecord.ToString();
if (!string.IsNullOrEmpty(bookContent))
CreateFile(clientFolderPath, bookName, bookContent);
}
}
}
}
catch (Exception ex)
{
log.Error($"Unable to retrieve Book for {bookId.ToString()} with URL", ex);
throw ex;
}
}
public IEnumerable<XElement> ParseBookXml(Stream response)
{
IEnumerable<XElement> bookRecords = null;
try
{
XDocument bookDoc = new XDocument();
bookDoc = XDocument.Load(response);
bookRecords = bookDoc.Root.Elements("bookReport").ToList();
return bookRecords;
}
catch (Exception ex)
{
log.Error($"Unable to load XML response from Rest Api Url .", ex);
return bookRecords;
}
}
public string GetBookName(XElement bookXmlRecord, int bookId)
{
string bookName = string.Empty;
string bookNumberString = String.Empty;
string bookNumberVal = bookXmlRecord.Element("bookNumber")?.Value;
DateTime bookDateVal = now(); // today date
bool validBookDate = DateTime.TryParse(bookXmlRecord.Element("BookDate")?.Value, out bookDateVal);
if (!validBookDate)
throw new InvalidCastException($"Unable to parse Book Date from rest api xml");
bookNumberString = GetBookNumberString(int.Parse(bookNumberVal));
bookName = $"Book-{bookId.ToString().PadLeft(4, '0')}-{reportDate:yyyyMMdd}{bookNumberString}.xml";
return bookName;
}
public bool CreateFile(string clientFolder, string fileName, string xmlResponse)
{
try
{
string filePath = $@"{clientFolder}\{fileName}";
if (!Directory.Exists(clientFolder))
Directory.CreateDirectory(clientFolder);
File.WriteAllText(filePath, xmlResponse);
return true;
}
catch (Exception ex)
{
log.Error($"Unable to create book in path {clientFolder}.", ex);
return false;
}
}