Skip to main content

Write and read XML files by serializing and deserializing objects with C#

This is a very useful approach when you don't want to create the XML files using XmlWriter

Posted in C#, Code snippets, Tutorials, XML

Have you ever wondered how to write an XML file easily? And what about reading the XML file and mapping into an object? There are cases we need to generate XML in order to send information here and there. Or even to use as a kind of database. And the most used approach (by my friends, at least) is to create the XML manually, defining every single node. Pro: More control of the output. Con: Time consuming.

And that brings us to the situation we had in the office.

We have access to a SQL database. But due the amount of security layers we end up taking a huge amount of time to develop against the database. Besides, we wanted to make something flexible and easy to be edited by anyone with more than 2 brain cells. That's why we decided that it would be much more flexible if we would use XML files for the data.

All we need is a well structured class, which could be a Model for those using MVC:

public class DummyClass
{
    public string Id { getset; }
    public string Name { getset; }
}

And the following code:

public class XmlSerializerHelper where T : class
{
	public static string Serialize(T obj)
	{
		var stringBuilder = new StringBuilder();
		try
		{
			var xmlWriterSettings = new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true };
			var ns = new XmlSerializerNamespaces();
			ns.Add("""");
			var xs = new XmlSerializer(typeof(T), "");
 
			using (var writer = XmlWriter.Create(stringBuilder, xmlWriterSettings))
			{
				xs.Serialize(writer, obj, ns);
			}
		}
		catch
		{
			throw;
		}
		return stringBuilder.ToString();
	}
 
	public static T Deserialize(string xmlString)
	{
		var reader = new StringReader(xmlString);
		var serializer = new XmlSerializer(typeof(T));
		var instance = (T)serializer.Deserialize(reader);
 
		return instance;
	}
}

If you want to serialize a class to XML:

xDoc.Add(XElement.Parse(XmlSerializerHelper<DummyClass>.Serialize(dummy)));

And if you want to deserialize:

var dummyObj = XmlSerializerHelper<DummyClass>.Deserialize(xDoc.ToString());

Please note a couple of things:

  1. This code will generate a very simple XML file, without namespaces or declarations;
  2. The "type of T" is there to give you flexibility when using the serialization/deserialization methods;
  3. The way the XML will be generated depends entirely on the way the class is created.

I know this code is not perfect (no try/catch on Deserialize, etc) it should give you a good head start. ;-)

If you start to implement this code you might have noticed one thing: Everything what is in the class will be serialized into the XML with the names you defined there. We can solve this and I will show you how.

Renaming the XML elements

It might happen that you have a class with a name which wouldn't make sense after generating a XML file. In that case it would be much better if we would have the XML elements in a way that anyone can understand. After all, it's much better to read than , right?

One easy way to do it is using Annotations over the name of the class and its properties. Here some that might be very useful:

XmlRoot

[XmlRoot("Person")]

XmlRoot will work in 2 ways: First by defining the root of your XML file; Second by defining its name. Recommended to be used to rename the class itself.

XmlAttribute

[XmlAttribute("Id")]

By default every property is serialized as XML element. By XmlAttribute you will tell the serializer that your property should be used as an attribute in the root element.

XmlElement

[XmlElement("Name")]

Use XmlElement in case you have a property you wish to rename. Very useful in the case you have a property called PersonName and you want to serialize it as Name.

XmlIgnore

[XmlIgnore]

You can use XmlIgnore when you don't want a property to be serialized.

XmlArrayItem

[XmlArrayItem("Children")]

XmlArrayItem is used to create sub elements. You can also use it to rename your properties which contains List, for example.

Of course there are more. But create a kind of ultimate xml serialization guide was never my idea. Maybe one day I will write a book about it. But while it doesn't happen I hope this article will be able to help some people around the interwebs.

Did you like the article?

You can subscribe and get them as soon they are online, share using the buttons bellow or leave a comment.

And you also can share using your favorite social network:

Replacing all non numeric characters from a string using Regex

Use this simple snipet to remove all dashes and dots from document numbers, license plates and so on

Posted in C#, Code snippets, Tutorials

Everybody who works coding something must use Regular Expressions (RegEx) at least once in a lifetime. They can be used for a lot of things but my favorite will be always matching and removing characters from a string.

One of the problems I always have developing softwares was with number formatting. While in the user interface we should allow dots and dashes as the user will never really care if he should or should not use it. In Brazil, for example, the postal code has the following format: 00000-000. Some people might put it without the dash. And that, my friend, will hurt the database.

One way to solve this is forcing the backend to keep only the numbers. Let's take a look on how to do it using Regex.Replace:

  1. Add the reference
    using System.Text.RegularExpressions;
  2. Use this line of code
    string onlyNumbers = Regex.Replace(str, "[^0-9]""");
    

And that's it!

Did you like the article?

You can subscribe and get them as soon they are online, share using the buttons bellow or leave a comment.

And you also can share using your favorite social network:

Using web.config to make your ASP.NET project accept LESS CSS

Learn how to solve the 404 error you get when you try to run an ASP.NET project with .less files

Posted in Tutorials, IIS, ASP.NET, Configuration

Every ASP.NET developer must love the web.config file. Seriously, I will write about it some day. :-)

Some time ago, we have faced a very interesting problem in one of our ASP.NET projects. We have decided to use LESS CSS in order to optimize the front-end development and speed up the things a bit. While we knew that we should compile the LESS files before throw it to production we were facing an error during the development phase:

HTTP Error 404.3 - Not Found

The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map.

The reason: IIS doesn’t support .less files by default.

By this time we have 2 solutions: The first one is to call the responsible for the webserver and ask him to add a new MIME type into the IIS. But thanks to the .NET architecture we don't need to do that. All we need to do is to add some extra lines to your web.config, inside , as seen bellow:

<system.webServer>
  <staticContent>
    <remove fileExtension=".less" />
    <mimeMap fileExtension=".less" mimeType="text/css" />
  staticContent>
system.webServer>

As you saw it’s simple, clear and useful. Keep in mind that you can use the same method to solve the problem with other non-supported files such as webfonts (.eot, .woof), videos (.mp4, .ogg, .m4v), images (.svg, .svgx) and so on (as Mads Kristensen wrote).

Did you like the article?

You can subscribe and get them as soon they are online, share using the buttons bellow or leave a comment.

And you also can share using your favorite social network:

How to upload a file using ASP.NET MVC and AJAX

A very simple file uploader using the progress bar component from Bootstrap

Posted in C#, Tutorials, ASP.NET, MVC, AJAX

I've decided to get my old upload post and upgrade the components I am using. For example: Before it was an MVC3 project made on Visual Studio 2010 using the old version of everything. Now it's a Visual Studio 2012 project, ASP.NET MVC4, using bootstrap and the newest version of each plugin I've used before.

First step

First of all we need to create a Model just like Scott Hanselman made in his article. Then we will have the name, length and type of our file:

public class UploadFilesResult
{
	public string Name { getset; }
	public int Length { getset; }
	public string Type { getset; }
}

Second step

We will need to create an Action Method which will take care of the upload. It will be called by using the http POST method, get the list of selected files and save into App_Data. This Action Method should return a json informing the name, length and type of the files:

[HttpPost]
public ContentResult UploadFiles()
{
	var r = new List<ViewDataUploadFilesResult>();
 
	foreach (string file in Request.Files)
	{
		HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;
		if (hpf.ContentLength == 0)
			continue;
 
		string savedFileName = Path.Combine(Server.MapPath("~/App_Data"), Path.GetFileName(hpf.FileName));
		hpf.SaveAs(savedFileName); // Save the file
 
		r.Add(new ViewDataUploadFilesResult()
		{
			Name = hpf.FileName,
			Length = hpf.ContentLength,
			Type = hpf.ContentType
		});
	}
	// Returns json
	return Content("{\"name\":\"" + r[0].Name + "\",\"type\":\"" + r[0].Type + "\",\"size\":\"" + string.Format("{0} bytes", r[0].Length) + "\"}""application/json");
}

Third step

After that we only need to download a jQuery plugin called jQuery File Upload. It brings us lots of cool stuff but, for the sake of simplicity, we are gonna use only 2 files (apart from the others I am already using): jquery.fileupload.css and jquery.fileupload.js:

Fourth step

We need now a way to send these files. This is what I've created - just for the upload - but you can adapt into your page:

<div class="container">
	<span class="btn btn-success fileinput-button">
		<i class="glyphicon glyphicon-plus">i>
		<span>Add files...span>
		<input id="fileupload" type="file" name="files[]" multiple>
	span>
	<br />
	<div class="progress">
		<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width0%;">
			<span class="sr-only">0% completespan>
		div>
	div>
	<br />
	<div class="file_name">div>
	<br />
	<div class="file_type">div>
	<br />
	<div class="file_size">div>
div>

Notice 4 things:

  1. I didn't use HtmlHelper to create the form. The reason is the ease to create the form without it. Also, we don't need to use HtmlHelpers all the time;
  2. I am not using a form tag. The plugin takes care of everything;
  3. The progress bar, thanks to bootstrap;
  4. The divs at the end, which will only receive the json data.

Last step

Now we need to make the javascript in order to make this work. I am using the jQuery File Upload plugin calling the Action Method UploadFiles created in the HomeController. In addition I have also attached an event which shows the upload status to the user by using the bootstrap progressbar component:

<script type="text/javascript">
	$(document).ready(function () {
		$('#fileupload').fileupload({
			dataType: 'json',
			url: '/Home/UploadFiles',
			autoUpload: true,
			done: function (e, data) {
				$('.file_name').html(data.result.name);
				$('.file_type').html(data.result.type);
				$('.file_size').html(data.result.size);
			}
		}).on('fileuploadprogressall'function (e, data) {
			var progress = parseInt(data.loaded / data.total * 100, 10);
			$('.progress .progress-bar').css('width', progress + '%');
		});
	});
script>

That's it. Now you are ready to add this feature to your website, without any postback.

Download the code here: jQueryFileUploadMVC4.zip (5.84 MB). Yes, almost 6MB thanks to the packages.

Did you like the article?

You can subscribe and get them as soon they are online, share using the buttons bellow or leave a comment.

And you also can share using your favorite social network:

How to reduce the size of a word document by optimizing the images in 5 easy steps

Very useful in case you get a huge .doc / .docx full of images

Posted in Misc, Tutorials

Some time ago, I got a word document with around 36 MB and a request to resize this file in order to be lighter as it be sent via e-mail. The first thing I thought was the obvious: Why not compact the file? I use 7-zip, which is the best compression utility I have ever used. It did not work as expected since the file went down to 30 MB.

The problem 

When I’ve opened the document I could see that it had only 10 pages, each with 2 images. So it could be possible the images were way too heavy, meaning, not optimized for internet or text documents. Do you know those people who take a picture using all megapixels of the digital camera and start to send those 4 MB files to everybody? This was more or less the case.

The solution

It’s simple: All we need is to reduce the dimensions of the images in the word document. But I am not saying about simply resizing, but editing. By editing we will be able to reduce every of those heavy images into something more acceptable. For that, I will use my favorite image visualizer, the XnView.

So, with the word document open:

  1. Right click on the image, select “Save as picture…”, define a name and save itd

  2. Open the saved image in the XnView

  3. Click on the menu “Image” and then “Resize” (or Shift + S)

  4. Choose the appropriated size and press Ok. Here is a bit tricky since it depends on the width/height the image actually should have according to your word document

  5. Save the image (File -> Save or Ctrl + S)

I’ve used 800 x 400 with this image and its size decreased from 7 MB to 65 KB. Now it is only about deleting the huge picture from the word document and add the new resized one. The result is a document with 78 KB, which is much better to send around the internet.

Note: This problem is going to happen if you insert the images by drag & drop. If you use the menu (Insert -> Pictures) the image will go through a process of optimization and the document will not be so heavy.

Did you like the article?

You can subscribe and get them as soon they are online, share using the buttons bellow or leave a comment.

And you also can share using your favorite social network: