Si habéis tenido que trabajar alguna vez con los blobs de Windows Azure Storage, y más aún si habéis hecho uso de los snapshot, ya habréis tenido el placer de encontraros con un error como este:
Si bien teníamos una forma de eliminar un blob con todos sus snapshots
blob.Delete(new BlobRequestOptions() { DeleteSnapshotsOption = DeleteSnapshotsOption.IncludeSnapshots });
Cuando queríamos eliminar uno solo la cosa se complica 🙁
Hasta ahora para recuperar un snapshot la única solución era llamar al método GetBlobReference con la siguiente estructura:
blob.GetBlobReference("filename?snapshot=<DateTime>");
Además la fecha debía tener el siguiente formato: 2010-03-07T00%3A12%3A14.1496934Z
La otra opción era dejar de lado el Storage Client y crear nuestra propia llamada REST con los parámetros oportunos.
En cualquiera de los dos casos no era una forma muy simplificada de llevar a cabo una acción tan sencilla como recuperar un snapshot hasta la versión 1.3 😀
A partir de ahora disponemos de una sobrecarga de CloudBlobClient.GetBlobReference (aunque yo lo habría puesto dentro de CloudBlobContainer o al menos poner la sobrecarga en ambos métodos GetBlobReference) a la cual podemos pasar como parámetros tanto la URI del blob como el DateTime del snapshot que queremos recuperar.
Un dato importante a tener en cuenta es que la fecha debe ser UTC y obviamente debe ser exacta a la almacenada. Digo esto por el incidente que tuve al intentar recuperar el DateTime desde un ActionLink de ASP.NET MVC:
<%: Html.ActionLink("Delete", "Delete", new { item.Uri, item.ContainerName, item.SnapShotTime})%>
Al hacer esto, lo que está ocurriendo es que realiza un ToString() del DateTime dejando fuera los milisegundos que tenía asociados el snapshotTime (gracias Bruno :D), por lo que la fecha exacta ya no coincide. En mi caso, en vez de permitir esta conversión, paso como parámetro directamente la propiedad Ticks la cual devuelve un long:
<%: Html.ActionLink("Delete", "Delete", new { item.Uri, item.ContainerName, item.SnapShotTime.Ticks })%>
De esta manera mantengo la fecha exacta y sólo necesitamos realizar la conversión a DateTime UTC en el servidor:
public void DeleteBlob(string uri, string containerName, long snapShotTimeTicks) { var container = GetContainer(containerName); CloudBlob blob; if (snapShotTimeTicks != 0) { var utcSnapshotTime = new DateTime(snapShotTimeTicks, DateTimeKind.Utc); blob = _blobClient.GetBlobReference(uri, utcSnapshotTime); } else blob = container.GetBlobReference(uri); blob.Delete(); }
Espero que sea de utilidad 🙂
¡Saludos!