2

I am creating a program that creates, writes, and saves an xml file. When I try to open the saved file I get an error that says the file cannot be accessed because it is being used by another process. I assumed it was because I didn't close the filestream after I saved the file so I made the correction. I still can't open the file and I receive the same error. I'm not sure what the issue is beyond this point. How can I fix this?

namespace XML_DataSets
{
    public partial class FormAddNew : Form
    {
        XmlSerializer xs;
        List<Class1> ls;

        //create the DataTable
        DataTable dt = new DataTable("Contact");
        XDocument xd = new XDocument();

        public FormAddNew()
        {
            InitializeComponent();

            ls = new List<Class1>();
            xs = new XmlSerializer(typeof(List<Class1>));

            //create columns for the DataTable
            DataColumn dc1 = new DataColumn("Id");
            dc1.DataType = System.Type.GetType("System.Int32");
            dc1.AutoIncrement = true;
            dc1.AutoIncrementSeed = 1;
            dc1.AutoIncrementStep = 1;

            //add columns to the DataTable
            dt.Columns.Add(dc1);
            dt.Columns.Add(new DataColumn("Name"));
            dt.Columns.Add(new DataColumn("Age"));
            dt.Columns.Add(new DataColumn("Gender"));

            //create DataSet
            DataSet ds = new DataSet();
            ds.DataSetName = "AddressBook";
            ds.Tables.Add(dt);
        }


        private void buttonCreate_Click(object sender, EventArgs e)
        {
            DataRow row = dt.NewRow();
            row["Name"] = textBoxName.Text;
            row["Age"] = textBoxAge.Text;
            row["Gender"] = textBoxGender.Text;

            dt.Rows.Add(row);
            dataGridView1.DataSource = dt;

            //dt.WriteXml("Contacts.xml");
            xd = WriteDt2Xml(dt);
        }

        public static XDocument WriteDt2Xml(DataTable dt)
        {
            using (var stream = new MemoryStream())
            {
                dt.WriteXml(stream);
                stream.Position = 0;
                XmlReaderSettings settings = new XmlReaderSettings();
                settings.ConformanceLevel = ConformanceLevel.Fragment;
                XmlReader reader = XmlReader.Create(stream, settings);
                reader.MoveToContent();
                if (reader.IsEmptyElement) { reader.Read(); return null; }
                return XDocument.Load(reader);
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Stream input = null;
            OpenFileDialog dialog = new OpenFileDialog();
            openFileDialog.Filter = "xml file | *.xml";
            openFileDialog.FilterIndex = 2;
            openFileDialog.RestoreDirectory = true;

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    if ((input = openFileDialog.OpenFile()) != null)
                    {
                        FileStream fs = new FileStream(@openFileDialog.FileName.ToString(), FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                        ls = (List<Class1>)xs.Deserialize(fs);
                        dataGridView1.DataSource = ls;
                        fs.Close();

                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "ERROR");
                }
            }
        }
    }
}

@Daniel Advise taken well...I refactored the code and see the error you referred to. I checked out the two links you provided as examples. I made corrections but I still get the same result.

tony
  • 305
  • 1
  • 3
  • 13
  • 1
    Quick guess: `XmlReader reader` is never disposed of. – tymtam Oct 16 '17 at 01:58
  • In addition to what @mayu suggested, do you get the error if you restart the computer then do nothing else but clean, rebuild and run it? – Missy Oct 16 '17 at 03:43
  • @Missy...yes that is correct. I'm currently research serialization to see where I went wrong. – tony Oct 16 '17 at 11:50
  • @mayu - the XmlReader reader is wrapped in a Using...so any process tied to it should be disposed once the Using is complete. – tony Oct 16 '17 at 12:56
  • @Daniel...thanks for all your help...This solution works. The reason I was using the dataset, table and grid is because I'm building the same solution over and over again so that I can get a firm grip on xml. I appreciate your help and time. Cheers! – tony Oct 17 '17 at 11:09
  • @Daniel...one thing...public List Contacts { get; set; } throws an error that says it is inconsistent accessibility – tony Oct 17 '17 at 11:29
  • @Daniel...there is no need for correction because the class "Contact" just need to be Public. – tony Oct 17 '17 at 11:39

1 Answers1

1

First change the way you open the file to:

using (var fs = new FileStream(@openFileDialog.FileName, FileMode.Open, FileAccess.Read))
{
    ls = (List<Class1>) xs.Deserialize(fs);
    dataGridView1.DataSource = ls;
}

an then try to check (Debug) the entire Exception in openToolStripMenuItem_Click event:

System.InvalidOperationException was caught
  HResult=-2146233079
  Message=There is an error in XML document (2, 2).
  Source=System.Xml
  StackTrace:
       at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
       at System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream)
       at WindowsFormsApplication1.FormAddNew.openToolStripMenuItem_Click(Object sender, EventArgs e) in c:\Users\admin\Documents\Visual Studio 2013\Projects\WindowsFormsApplication1\WindowsFormsApplication1\FormAddNew.cs:line 131
  InnerException: System.InvalidOperationException
       HResult=-2146233079
       Message=<AddressBook xmlns=''> was not expected. --The problem!
       Source=Microsoft.GeneratedCode
       StackTrace:
            at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderList1.Read3_ArrayOfClass1()
       InnerException: 

Then read:

xmlns='' was not expected when deserializing nested classes

{"<user xmlns=''> was not expected.} Deserializing Twitter XML

Update:

You need an atomic object when desalinizing like:

public class AddressBook
{
    public AddressBook()
    {
        Contacts = new List<Contact>();
    }

    public List<Contact> Contacts { get; set; }
}

public class Contact
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Age { get; set; }
    public string Gender { get; set; }
}

and I would suggest to get rid of xDocument, DataSet & DataTable. they add too much complication for nothing. and I guess the reason u r using them because of DataGrid which is minor concern, focus on coding first:

private readonly XmlSerializer xs;
private AddressBook ls;
private int _counter = 0;

public FormAddNew2()
{
    InitializeComponent();

    ls = new AddressBook();
    xs = new XmlSerializer(typeof(AddressBook));
}

private void buttonCreate_Click(object sender, EventArgs e)
{
    var addressBookContact2 = new Contact
    {
        Id = ++_counter,
        Name = textBoxName.Text,
        Age = textBoxAge.Text,
        Gender = textBoxGender.Text
    };

    ls.Contacts.Add(addressBookContact2);

    dataGridView1.DataSource = null; // strangly u need this
    dataGridView1.DataSource = ls.Contacts;
}

private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
    var saveFileDialog = new SaveFileDialog();
    saveFileDialog.InitialDirectory = @"C:\";
    saveFileDialog.RestoreDirectory = true;
    saveFileDialog.Title = "Select save location file name";
    saveFileDialog.Filter = "XML-File | *.xml";
    if(saveFileDialog.ShowDialog() == DialogResult.OK)
    {
        using(var writer = new StreamWriter(saveFileDialog.FileName))
        {
            xs.Serialize(writer, ls);
            MessageBox.Show(saveFileDialog.FileName);
        }
    }
}

private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
    var openFileDialog = new OpenFileDialog();
    openFileDialog.Filter = "xml file | *.xml";
    openFileDialog.FilterIndex = 2;
    openFileDialog.RestoreDirectory = true;

    if(openFileDialog.ShowDialog() == DialogResult.OK)
    {
        try
        {
            using (var reader = new StreamReader(@openFileDialog.FileName))
            {
                ls = (AddressBook) xs.Deserialize(reader);
                _counter = 0;
                dataGridView1.DataSource = ls.Contacts;
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString(), "ERROR");
        }
    }
}
Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Daniel B
  • 3,109
  • 2
  • 33
  • 42
  • @Daniel...I am researching this. I'll post what I find – tony Oct 16 '17 at 11:51
  • @tony it would be helpful if u post Class1 code. I guessed myself – Daniel B Oct 16 '17 at 14:00
  • @Daniel...I posted it...this is driving me crazy. – tony Oct 16 '17 at 14:20
  • 1
    fix this first: using (var fs = new FileStream(@openFileDialog.FileName, FileMode.Open, FileAccess.Read)) { ls = (List) xs.Deserialize(fs); dataGridView1.DataSource = ls; } – Daniel B Oct 16 '17 at 16:22
  • @Daniel...I tried the suggested changes and I get the same results. Just for clarification, are you seeing a problem with the openfiledialog? As I said the suggested changes yielded the same results. – tony Oct 16 '17 at 16:39
  • @Daniel...for the savefiledialog - I also tried the suggested changes and yielded the same results. – tony Oct 16 '17 at 16:43
  • @tony it's related to open the file. but u should get another exception: "There is an error in XML document (2, 2)" – Daniel B Oct 16 '17 at 16:43
  • Strange. Can u pick up the FormAddNew from http://rextester.com/FJVQZ49471 and try – Daniel B Oct 16 '17 at 19:21
  • var openFileDialog = new OpenFileDialog(); not OpenFileDialog dialog = new OpenFileDialog(); – Daniel B Oct 16 '17 at 19:22
  • Ok I used your edited version of FormAddNew and I get the same error. It seems my schema is missing this...xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"...is that causing the error...because the xml itself appears to be in order. – tony Oct 16 '17 at 19:34
  • 1 2 2 2 2 23 23 23 3 234 234 234 – tony Oct 16 '17 at 19:35
  • A new error! it's different than yr original "File can't be accessed because it's being used by another process".Now read https://stackoverflow.com/questions/2797763/xmlns-was-not-expected-when-deserializing-nested-classes https://stackoverflow.com/questions/1556874/user-xmlns-was-not-expected-deserializing-twitter-xml to resolve it. it's about namespace – Daniel B Oct 16 '17 at 19:44