diff --git a/src/Project/Controllers/MetadataController.cs b/src/Project/Controllers/MetadataController.cs
index 8a69e4a5abbaf57c6a55564103daa8868d2dc634..db5099ae32f7d84448fc1bf2032efc459b2aa211 100644
--- a/src/Project/Controllers/MetadataController.cs
+++ b/src/Project/Controllers/MetadataController.cs
@@ -112,7 +112,8 @@ namespace Coscine.Api.Project.Controllers
             if (_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member))
             {
                 var id = _metadataModel.GenerateId(resourceId, filename, version);
-                var graph = _util.GetGraph(id);
+                var uri = _metadataModel.CreateUri(id);
+                var graph = _util.GetGraph(uri);
                 return Json(JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter())).ToString());
             }
             else
@@ -126,7 +127,7 @@ namespace Coscine.Api.Project.Controllers
         {
             var innerBlock = ObjectFactory<JToken>.DeserializeFromStream(Request.Body);
             var graphName = _metadataModel.GenerateId(resourceId, filename, version);
-            var graphNameUri = new Uri(graphName);
+            var graphNameUri = _metadataModel.CreateUri(graphName);
             var json = new JObject
             {
                 [graphName] = innerBlock
diff --git a/src/Project/Models/MetadataModel.cs b/src/Project/Models/MetadataModel.cs
index 5ce7769ae026c19d7af1930a9032d6516fa0cebb..a5f3cee395e4fa0a8cfc7a6b5a5963e237f0fd4e 100644
--- a/src/Project/Models/MetadataModel.cs
+++ b/src/Project/Models/MetadataModel.cs
@@ -5,6 +5,7 @@ using LinqToDB;
 using System;
 using System.Linq;
 using System.Linq.Expressions;
+using System.Web;
 
 namespace Coscine.Api.Project.Models
 {
@@ -50,7 +51,15 @@ namespace Coscine.Api.Project.Models
 
         public string GenerateId(string resourceId, string filename, string version)
         {
-            return $"https://purl.org/coscine/md/{resourceId}/{filename}/{version}/";
+            // Double UrlEncode since converting it to Uri executes one UrlDecode and Virtuoso
+            // graph names don't support special characters
+            var encodedFileName = HttpUtility.UrlEncode(HttpUtility.UrlEncode(filename));
+            return $"https://purl.org/coscine/md/{resourceId}/{encodedFileName}/{version}/";
+        }
+
+        public Uri CreateUri(string graphName)
+        {
+            return new Uri(graphName);
         }
     }
 }