-2

I am currently making a simple tool that allows you to make different types of searches at once. So far I have done this by implementing a Site class, creating a list of sites I would like to search, then opening a new window with a Browser element with the search URL that I need for each active site.

There is also a method that creates a new site and adds it to the list.

Site.cs

public class Site
    {
        public int type { get; set; }
        public string URL { get; set; }
        public string extras { get; set; }
        public string name { get; set; }
        public bool IsChecked { get; set; }
    

        public Uri GetMySearch(string query)
        {
            switch (type)
            {
                case 0: //Simple Search
                    return new Uri(URL + query);
                case 1: //API call
                    return new Uri(URL + query + extras);
                default: return null;
            }
        }
    }

some parts of Mainwindow.Cs

        private void Window_Loaded(object sender, RoutedEventArgs e)   //initialization
        {
            Site Google = new Site();
            Google.URL = "https://google.com/search?q=";
            Google.type = 0;
            Google.name = "google";

            Site Wolfram = new Site();
            Wolfram.URL = "https://api.wolframalpha.com/v1/simple?i=";
            Wolfram.type = 1;
            Wolfram.extras = "&appid=2GA4A5-YL7HY9KR42";
            Wolfram.name = "Wolfram";

            Site Wikipedia = new Site();
            Wikipedia.URL = "https://google.com/search?q=site:wikipedia.org";
            Wikipedia.type = 0;
            Wikipedia.name = "Wikipedia";

            sites.Add(Google);
            sites.Add(Wolfram);
            sites.Add(Wikipedia);

            SitesDisplay.ItemsSource = sites;
        }

        private void AddNewSiteButton(object sender, RoutedEventArgs e)
        {
            SiteEntryWindow siteEntryWindow = new SiteEntryWindow("Enter the display name of your site \nOr leave blank to default to URL");
            if (siteEntryWindow.ShowDialog() == true)
            {
                if (siteEntryWindow.url.Length > 3)
                    AddASite(siteEntryWindow.url, siteEntryWindow.MyName);
                else MessageBox.Show("Please enter a valid url!", "Oops!", MessageBoxButton.OK, MessageBoxImage.Error);

            }
           
        }

        public void AddASite(string url, string name = "")
        {
            Site mySite = new Site();
            if (name.Length > 0)
                mySite.name = name;
            else mySite.name = url;
            mySite.URL = "https://google.com/search?q=site:" + url;
            mySite.type = 0;
            sites.Add(mySite);
            SitesDisplay.ItemsSource = null;
            SitesDisplay.ItemsSource = sites;
        }

Essentially I am trying to figure out how I can save the users list of sites to a txt file (or whatever would be more applicable in this case) and then load it when the application opens. I tried using StreamWriter and WriteAllLines but since it is a list of sites they do not know what to do.

I could probably use lots of if else to process each individual class attribute into strings and then write it to a txt file but I would have to parse it whenever I would want to load and I cannot imagine that would be easy.

This person seemed to be having a similar issue but I'm not sure if an XML file is the best solution and XmlSerializer seemed to be beyond me. Is there a simpler / better way to do this?

I am still somewhat new to C# and WPF so sorry if this is a silly question or has a easy solution.

roglemorph
  • 13
  • 3
  • 1
    You could look into using .NET's built-in tool for this, Application Settings. Here's a starting point, via another answer on StackOverflow: [approach for saving user settings](https://stackoverflow.com/a/3784591/3791245) – Sean Skelly Sep 23 '20 at 23:05
  • You also might do some reading on Serialization/Deserialization, depending on your needs. For more information, see: [Serialization (C#)](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/serialization/) – Rufus L Sep 23 '20 at 23:13
  • XmlSerializer is really quite simple once you get the hang of it, I'd suggest spending a bit of time reading the various online tutorials on it. – Tim Rutter Sep 24 '20 at 08:11

1 Answers1

1

You can serialize your Site collection to JSON and save the JSON object to a file (BinaryFormatter is obsolete for security reasons).

The following example uses System.Text.Json.JsonSerializer and requires a reference to "System.Text.Json.dll" being added to the project. If you are not using .NET Core >=3.0 or .NET 5.0 you can install the package using the NuGet Package Manager (in case the assembly is not available via the reference browser).

private async Task SerializeToFileAsync<TValue>(TValue valueToSerialize, string destinationFilePath)
{
  string jsonData = System.Text.Json.JsonSerializer.Serialize(valueToSerialize);
  using (var destinationFile = new FileStream(destinationFilePath, FileMode.Create))
  {
    using (var streamWriter = new StreamWriter(destinationFile))
    {
      await streamWriter.WriteAsync(jsonData);
    }
  }
}

private async Task<TValue> DeserializeFromFileAsync<TValue>(string sourceFilePath)
{
  using (var sourceFile = new FileStream(sourceFilePath, FileMode.Open))
  {
    using (var streamReader = new StreamReader(sourceFile))
    {
      string fileContent = await streamReader.ReadToEndAsync();
      return System.Text.Json.JsonSerializer.Deserialize<TValue>(fileContent);
    }
  }
}

Example

var sites = new List<Site>
{
  new Site
  {
    Google.URL = "https://google.com/search?q=",
    Google.type = 0,
    Google.name = "google"
  }
};

// Save list of Site to "sites.txt"
await SerializeToFileAsync(sites, "sites.txt");

// Load list of Site from "sites.txt"
List<Site> sites = await DeserializeFromFileAsync<List<Site>>("sites.txt");
BionicCode
  • 1
  • 4
  • 28
  • 44
  • Thank you this was a good starting point. I couldn't really figure out how to add the reference you were talking about, but If anyone else is having the same issue I used https://www.newtonsoft.com/json and it worked well. – roglemorph Sep 24 '20 at 17:51