2

I have absolutely no experience with XML, let alone generating XML files, and I'm completely stuck.

I couldn't find any MVC related threads about this, just WPF and console.

I think I have a working code to generate a file judging by MSDN's guide, but I don't know how to move on from there in MVC as this was for console.

This is in the repository:

public void SaveFile(string fileName)
    {
        Checker checker = new Checker();
        XMLWriter xmlWriter = new XMLWriter();

        string userid = xmlWriter.UserId.ToString();
        string date = xmlWriter.Date;
        int hours = xmlWriter.Hours;
        string role = xmlWriter.Role;

        userid = checker.User.UserName;
        date = checker.Date.ToString();
        hours = int.Parse(checker.Total.ToString());
        role = checker.User.Roles.ToString();

        XDocument doc = new XDocument(
            new XElement("Tidrans",
                new XElement("tidkod", role),
                new XElement("datum", date),
                new XElement("timmar", hours)
            )
        );
        doc.Save("Test.xml");

    }

And this is in the model:

public class XMLWriter
{
    [Key]
    public int Id { get; set; }

    [Display(Name = "anstid")]
    public int UserId { get; set; }

    [Display(Name = "tidkod")]
    public string Role { get; set; }

    [Display(Name = "datum")]
    public string Date { get; set; }

    [Display(Name = "timmar")]
    public int Hours { get; set; }

    [Display(Name = "frånvarande")]
    public float Absent { get; set; }
}

I don't know how to go from there, how do i use the controller? Do I need a controller? How do I download it?

3
  • 1
    I think you should know why are you moving to MVC and not something else, and that should answer the question "Do I need a controller" the rest should follow.. the code is not bound to console apps, so should work the same way. Eventually you can have some sort of helper class that generates the XML, but I can't see you working with MVC without a controller.. maybe I'm wrong, but give it a try. Commented Sep 28, 2017 at 10:35
  • This is a feature of a web app I'm building. Most of it is already done, all that's really needed is a way to export the data (e.g XML). So the reason why I'm asking if I need a controller is for this particular feature. Commented Sep 28, 2017 at 11:34
  • If the solution already exists, you can just add a helper class and instantiate or inject.. up to you, you don't need a controller just to generate or download xml. Commented Sep 28, 2017 at 11:37

4 Answers 4

6

I suppose that you want the xml to be downloaded. If that's the case try the below code:

    public FileStreamResult GenerateXML()
    {
        MemoryStream ms = new MemoryStream();
        XmlWriterSettings xws = new XmlWriterSettings();
        xws.OmitXmlDeclaration = true;
        xws.Indent = true;

        using (XmlWriter xw = XmlWriter.Create(ms, xws))
        {
            XDocument doc = new XDocument(
             new XElement("Tidrans",
              new XElement("tidkod", "role"),
              new XElement("datum", "date"),
              new XElement("timmar", "hours")
             )
            );
            doc.WriteTo(xw);
        }
        ms.Position = 0;
        return File(ms, "text/xml", "Sample.xml");
    }

Below is the output:

<Tidrans>
  <tidkod>role</tidkod>
  <datum>date</datum>
  <timmar>hours</timmar>
</Tidrans>
Sign up to request clarification or add additional context in comments.

3 Comments

I had to change some things (moved it over to the controller to get File to work and moved return inside the first using method), but now I get this error. Oh, and I should add that to make sure that it "works" I replaced the checkin stuff with test strings (commented out the integers), just to be sure that there're values.
thank you, it works great! I shouldn't have too much of a problem to get data in there. And you didn't bother me, I'm sorry for bothering you. I guess it's easy to get one "tidtrans" for each user, just a foreach? I shouldn't have any problems with that, just making sure (no need for any examples, you've already been very helpful). Thanks again!
Instead of your own MemoryStream and XmlWriter, you could make use MVC's intrinsic properties, Response.OutputStream and Response.Output respectively. See my post below.
1

You need to determine how you want to handle this. Given the method you already have, all you need to do is "run" it. It could be a controller action that does that, a console app, an Azure Function, etc. The possibilities are endless. Once it has run, you can serve the XML file directly via IIS. You don't even need MVC, as it's just a static file at that point.

However, if you want to generate it on the fly, that's where a controller action would come in to play. Then, you could either call this method in that action and return the created file directly:

return File("Test.xml", "application/xml");

Or you could have that method actually be the content of your action itself, and return the XML directly without saving to the filesystem:

return Content(doc.ToString(), "application/xml");

Comments

1

This is presumably the most simple yet efficient way to return XML content in response:

public ActionResult XmlData()
{
    var doc = new XDocument(
        new XElement("Root",
            new XElement("Node1", 1),
            new XElement("Node2", 2)
        )
    );

    Response.ContentType = "text/xml";

    doc.Save(Response.Output);

    return new EmptyResult();
}

If your XML document is large enough, you could streamline the output by getting rid of the XDocument and writing directly to response stream.

Comments

-2
[HttpPost]
public ActionResult Upisi(string reg, string datum, string startPos, string krajPos, string predjKm) {
    // upisivanje u fajl
    List<vozilo> vozila = TempData["vozila"] as List<vozilo>;
    List<voziloPodatak> ispis = new List<voziloPodatak>();

    string marka = "";
    string godina = "";
    int kilometri = 0;

    foreach (vozilo voz in vozila) {
        if (voz.Registracija == reg) {
            marka = voz.Model;
            godina = voz.Godiste;
        }
    }

    StreamWriter sw = new StreamWriter(Server.MapPath("~/App_Data/" + reg + ".txt"), true);       

    sw.WriteLine(datum + "|" + startPos + "|" + krajPos + "|" + predjKm);

    sw.Close();

    foreach (vozilo voz in vozila) {
        voziloPodatak podatak = new voziloPodatak();
        bool postoji = System.IO.File.Exists(Server.MapPath("~/App_Data/" + voz.Registracija + ".txt"));
        if (postoji)
        {
            podatak.Registracija = voz.Registracija;
            podatak.Marka = voz.Model;
            podatak.GodinaProizvodnje = voz.Godiste;

                using (StreamReader sr = new StreamReader(Server.MapPath("~/App_Data/" + voz.Registracija + ".txt")))
                {

                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        string[] linija = line.Split('|');
                        int predjenoKmFajl = Convert.ToInt32(linija[3]);
                        kilometri += predjenoKmFajl;
                    }

                }
                podatak.PredjenoKilometara = kilometri.ToString();                

            ispis.Add(podatak);
        }
    }       
    return View(ispis);
}

1 Comment

I can't read this code as it seems to be in Polish or Czech. Please translate it into English and add an explanation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.