2
\$\begingroup\$

I have the following code in PHP that appends a file path with a timestamp of when it was last modified:

function AssetTimestamp($filename)
{
    if (file_exists($filename)) {
        return $filename . '?' . @filemtime($filename);
    } else {
        return $filename;
    }
}

I have written the equivalent in C#

public static string AssetTimestamp(string filename)
    {
        if (System.IO.File.Exists(HttpContext.Current.Server.MapPath(filename)))
        {
            DateTime dt = System.IO.File.GetLastWriteTimeUtc(HttpContext.Current.Server.MapPath(filename));
            Int32 unixTimestamp = (Int32)(dt.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
            return System.Web.VirtualPathUtility.ToAbsolute(filename) + "?" + unixTimestamp;
        }
        else
        {
            return System.Web.VirtualPathUtility.ToAbsolute(filename);
        }
    }

But as you can see, the code is HUGE in comparison! Can anyone suggest some better ways to handle this, as I can't believe that PHP can do all of that in just one line compared to all the crazy MapPath and converting of dates etc.

\$\endgroup\$
3
\$\begingroup\$

The conversion of the code isn't that easy because of two key differences between PHP and ASP.NET:

  • .NET doesn't do Unix timestamps, so you'll have to introduce a conversion from DateTime to timestamp.
  • ASP.NET doesn't set the current directory to your application's directory, so relative paths aren't going to point to files existing in your web application.

So all code you have there is relevant. Not shorter, but more readable and less repetitive is the following:

using System.IO;

public static string AssetTimestamp(string filename)
{
    string filePath = HttpContext.Current.Server.MapPath(filename);
    string absoluteUri = System.Web.VirtualPathUtility.ToAbsolute(filename);

    if (!File.Exists(filePath))
    {
        return absoluteUri;
    }

    DateTime dt = File.GetLastWriteTimeUtc(filePath);
    int unixTimestamp = (int)(dt.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
    return absoluteUri + "?" + unixTimestamp;   
}
\$\endgroup\$
1
\$\begingroup\$

A construct like

if (condition) 
{
    return someValue;
}
else
{
    return someOtherValue;
}  

should be simplified to either

if (condition) 
{
    return someValue;
}
return someOtherValue;  

or using a tenary expression to

return condition ? someValue : someOtherValue;  

where I prefer the first, because it is more clear imho.


You could "hide" the longer code in an extension method like

public static class DateTimeExtension
{
    public static string GetUnixTimeStamp(this DateTime dateTime)
    {
        if (dateTime == null) { throw new ArgumentNullException("dateTime"); }
        return (dateTime.Subtract(new DateTime(1970, 1, 1))).TotalSeconds.ToString();
    }
}

which would result in this

public static string AssetTimestamp(string filename)
{
    if (System.IO.File.Exists(HttpContext.Current.Server.MapPath(filename)))
    {
        DateTime dt = System.IO.File.GetLastWriteTimeUtc(HttpContext.Current.Server.MapPath(filename));
        return System.Web.VirtualPathUtility.ToAbsolute(filename) + "?" + dt.GetUnixTimeStamp();
    }
    return System.Web.VirtualPathUtility.ToAbsolute(filename);
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.