Here is my straight-forward HTML 5 solution shown using an MVC Razor Form, but you could use a plain html form just as well. This solves the problem with the Input type=file not rendering the same in all browsers. You could style the browseBtn however you like by setting a background image for it. I tested this in IE 11, Firefox, and Chrome. IMO, the look of the default Chrome native control (shown in the question) is unacceptable.
Index.cshtml
<h2>Index</h2>
@using (Html.BeginForm("postFile", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div style="display:inline-block; margin-bottom:10px">
<input type="text" name="uploadControl" id="uploadControl"
style="width: 400px; height: 1.1em;" readonly="true" >
<button type="button" id="browseBtn" >Browse...</button>
</div>
<input type="file" name="upfile" id="upfile" style="display:none;" >
<button type="submit" id="uploadbtn" style="display:block">Click to upload</button>
<br><br>
@ViewBag.Message
}
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/UploadFile.js"></script>
UploadFile.js
$('#browseBtn').click(function () {
$('#upfile').first().trigger("click"); //cause the browse menu to pop up
});
$('#upfile').first().change(function (event) {
event.preventDefault();
var fileName = $('#upfile').val();
if (fileName && fileName.length > 0) {
$('#uploadControl').val(fileName);
}
});
HomeController.cs
public ActionResult postFile(HttpPostedFileBase upfile)
{
if (upfile != null && upfile.ContentLength > 0)
{
try
{
string path = Path.Combine(Server.MapPath("~/Images"),
Path.GetFileName(upfile.FileName));
//upfile.SaveAs(path);
ViewBag.Message = Path.GetFileName(upfile.FileName) + " uploaded successfully";
}
catch (Exception ex)
{
ViewBag.Message = "ERROR:" + ex.Message.ToString();
}
}
else
{
ViewBag.Message = "You have not specified a upfile.";
}
return View("Index");
}