Programmatically Extract or Unzip Zip, Rar Files and Check
In this post, we will see how we can extract or unzip the uploaded files and check for some files in it in a programmatic manner. We will use a normal MVC application to work with this demo. Read on for more info.
Join the DZone community and get the full member experience.
Join For FreeIn this post, we will see how we can extract or unzip the uploaded files and check for some files in it in a programmatic manner. We will use a normal MVC application to work with this demo. We will use Microsoft System.IO.Compression, System.IO.Compression.FileSystem namespaces and the classes, for example, ZipArchive, in the namespace for extracting or unzipping the files we upload. Once it is uploaded, we will check the same by looping through it. For the client side coding, we use jQuery. I guess this is enough for the introduction, now we will move on to our application. Let's create it. I hope you will like this article.
Download the Source Code
You can always download the source code here:
Background
As you are aware, most websites accept only .zip or any other zipped formats, this is for ensuring that only less amount of data is being uploaded to the server. We can reduce almost 60 percentage of the size if we zipped the same. Now the problem is, how you can validate any zipped item which is uploaded to your site? How can you check for any particular file in that zipped item? For example, if you need to find out any files with extension of .sql, .ico, or .txt? What if you want to intimate user that the uploaded items do not have any particular file that must be needed? You need to loop through the contents available in it right? This is what we are going to discuss in this post. I had a situation of uploading my old backups of my personal website (http://sibeeshpassion.com/) and, after uploading, I wanted to check whether the uploaded .zip file has .ico file in it. The process we are going to do is listed below.
Using the Code
Now we will move into the coding part. I hope your MVC application is ready for action with all of the needed packages.
Create a Controller
Now we will create a controller view with an action in it as follows.
public ActionResult Index()
{
return View();
}
Update the View
Now in the view, we will add a file upload and other needed elements.
<input type="file" name="FileUpload1" id="fileUpload" placeholder="Please select the file" /><br />
<input id="btnUploadFile" type="button" value="Upload File" />
<div id="message"></div>
Add the JS References
Add the references as follows.
<script src="~/scripts/jquery-1.10.2.min.js"></script>
<script src="~/scripts/MyScript.js"></script>
Here MyScript.js is where we are going to write some scripts.
Style the Elements (Optional)
You can style your view as follows. This step is absolutely optional, for me, the view should not be as simple as the default one. And, to be frank, I am not a good designer
<style>
#fileUpload {
border: 1px solid #ccc;
padding: 10px;
border-radius: 5px;
font-size: 14px;
font-family: cursive;
color: blue;
}
#btnUploadFile {
border: 1px solid #ccc;
padding: 10px;
border-radius: 5px;
font-size: 14px;
font-family: cursive;
color: blue;
}
#message {
border-radius: 5px;
font-size: 14px;
font-family: cursive;
color: blue;
margin-top: 15px;
}
h2 {
border-radius: 5px;
font-size: 20px;
font-family: cursive;
color: blue;
margin-top: 15px;
}
</style>
Add the Upload Action in Script
Now it is time to create the upload action. For that, please go to the script file MyScript.js and do the coding as follows.
$(document).ready(function () {
$('#btnUploadFile').on('click', function () {
var data = new FormData();
var files = $("#fileUpload").get(0).files;
// Add the uploaded image content to the form data collection
if (files.length > 0) {
data.append("UploadedImage", files[0]);
}
// Make Ajax request with the contentType = false, and procesDate = false
var ajaxRequest = $.ajax({
type: "POST",
url: "Home/Upload",
contentType: false,
processData: false,
data: data,
success: function (data) {
$('#message').html(data);
},
error: function (e)
{
console.log('Oops, Something went wrong!.' + e.message);
}
});
ajaxRequest.done(function (xhr, textStatus) {
// Do other operation
});
});
});
If you are not aware of uploading and downloading in MVC, I strongly recommend you to have a look here: Uploading and Downloading in MVC Step-by-Step.
So, we have set Home/Upload as the URL action in our Ajax function, right? So, we are going to create that action. Go to your controller and create a JsonResult action as follows.
public JsonResult Upload()
{
string isValid = checkIsValid(Request.Files);
return Json(isValid, JsonRequestBehavior.AllowGet);
}
So we have done that too, now stop for a while. To work with ZipArchive class you must include the namespace as listed below.
using System.IO.Compression;
Now, you will be shown an error like “Are you missing an assembly reference?” Yes we are. We have not added the references, right? So, now we are going to add the references for System.IO.Compression and System.IO.Compression.FileSystem.
Right click on Reference in your project and browse for the references. If you use Visual Studio 2015, the references will be in C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.
Please be noted that the folder names will differ according to your framework version
Compression_References
Now, we will go back to our controller and write the code for the function checkIsValid(Request.Files)
private string checkIsValid(HttpFileCollectionBase files)
{
string isValid = string.Empty;
try
{
foreach (string upload in Request.Files)
{
if (Request.Files[upload].ContentType == "application/octet-stream") //Content type for .zip is application/octet-stream
{
if (Request.Files[upload].FileName != "")
{
string path = AppDomain.CurrentDomain.BaseDirectory + "/ App_Data / uploads /";
if (!Directory.Exists(path))
{
// Try to create the directory.
DirectoryInfo di = Directory.CreateDirectory(path);
}
string filename = Path.GetFileName(Request.Files[upload].FileName);
string pth = Path.Combine(path, filename);
Request.Files[upload].SaveAs(pth);
isValid = CheckForTheIcon(pth);
}
}
else
{
isValid = "Only .zip files are accepted.";
}
}
return isValid;
}
catch (Exception)
{
return "Oops!. Something went wrong";
}
}
As you can see, we are looping through the HttpFileCollectionBase files and checking for the content type first.
Please be noted that the content type for the .zip file is application/octet-stream
Once the checking is done, we will save the files to a folder and send the path to the function CheckForTheIcon(pth). So, the next thing we need to do is to create the function CheckForTheIcon().
private string CheckForTheIcon(string strPath)
{
string result = string.Empty;
try
{
using (ZipArchive za = ZipFile.OpenRead(strPath))
{
foreach (ZipArchiveEntry zaItem in za.Entries)
{
if (zaItem.FullName.EndsWith(".ico", StringComparison.OrdinalIgnoreCase))
{
result = "Success";
}
else
{
result = "No ico files has been found";
}
}
}
return result;
}
catch (Exception)
{
result = "Oops!. Something went wrong";
return result;
}
}
As you can see, we are looping through each ZipArchive class item and checking for the ‘.ico’ file in it. So, if there is no error and there is ‘.ico’ file in the uploaded item zip item, you will get the message “Success: or if it does not contain the ‘.ico’ file, you will get the message as “No ico files has been found”.
Now it is time to see our output. Please run your application.
Output
If_you_try_to_upload_not_zipped_item
If_you_try_to_upload_zipped_item_which_does_not_have_ico_file
If_you_try_to_upload_zipped_item_which_have_ico_file
Conclusion
Did I miss anything that you may think which is needed? Have you ever wanted to do this requirement? Could you find this post as useful? I hope you liked this article. Please share me your valuable suggestions and feedback.
Published at DZone with permission of Sibeesh Venu, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments