diff --git a/wcs/fields.py b/wcs/fields.py
index f98d507..d5ac076 100644
--- a/wcs/fields.py
+++ b/wcs/fields.py
@@ -645,6 +645,9 @@ class FileField(WidgetField):
             return ['[download]files/%s/%s' % (self.id, value.base_filename)]
         return ['%s' % value]
 
+    def get_json_value(self, value):
+        return {'field_id': self.id, 'filename': value.base_filename}
+
     def perform_more_widget_changes(self, form, kwargs, edit = True):
         if not edit:
             value = get_request().get_field(self.field_key)
diff --git a/wcs/formdata.py b/wcs/formdata.py
index 5f71ee9..7f01fdf 100644
--- a/wcs/formdata.py
+++ b/wcs/formdata.py
@@ -28,17 +28,16 @@ from qommon.substitution import Substitutions
 def get_dict_with_varnames(fields, data):
     new_data = {}
     for field in fields:
-        if not hasattr(field, str('get_view_value')):
+        if not hasattr(field, 'get_view_value'):
             continue
         if data is not None:
-            raw_value = data.get(field.id)
+            value = data.get(field.id)
             if field.convert_value_to_str:
-                raw_value = field.convert_value_to_str(raw_value)
+                value = field.convert_value_to_str(value)
             display_value = data.get('%s_display' % field.id)
         else:
-            raw_value = ''
+            value = ''
             display_value = ''
-        value = display_value or raw_value
         # add it as f$n$
         new_data['f%s' % field.id] = value
 
@@ -48,9 +47,11 @@ def get_dict_with_varnames(fields, data):
 
         # and finally add it as its manually defined variable name
         if field.varname:
-            new_data['var_%s' % field.varname] = value
-            if display_value:
-                new_data['var_%s_raw' % field.varname] = raw_value
+            if field.store_display_value:
+                new_data['var_%s_raw' % field.varname] = value
+                new_data['var_%s' % field.varname] = display_value
+            else:
+                new_data['var_%s' % field.varname] = value
     return new_data
 
 def flatten_dict(d):
@@ -62,6 +63,33 @@ def flatten_dict(d):
             del d[k]
 
 
+def get_json_dict(fields, data):
+    new_data = {}
+    for field in fields:
+        if not field.varname: # exports only named fields
+            continue
+        if data is not None:
+            value = data.get(field.id)
+            if value and hasattr(field, 'get_json_value'):
+                value = field.get_json_value(value)
+            display_value = data.get('%s_display' % field.id)
+        else:
+            value = display_value = None
+        if field.store_display_value:
+            new_data[field.varname + '_raw'] = value
+            new_data[field.varname] = data.get('%s_display' % field.id)
+        else:
+            new_data[field.varname] = value
+    return new_data
+
+class JSONEncoder(json.JSONEncoder):
+    def default(self, obj):
+        if isinstance(obj, time.struct_time):
+            return time.strftime('%Y-%m-%dT%H:%M:%S', obj)
+        # Let the base class default method raise the TypeError
+        return json.JSONEncoder.default(self, obj)
+
+
 class Evolution:
     who = None
     status = None
@@ -401,18 +429,14 @@ class FormData(StorableObject):
 
     def export_to_json(self):
         data = {}
-
         data['id'] = '%s/%s' % (self.formdef.url_name, self.id)
         data['display_id'] = self.get_display_id()
-
-        if self.receipt_time is not None:
-            data['receipt_time'] = qommon.strftime.strftime('%Y-%m-%dT%H:%M:%S', self.receipt_time)
+        data['receipt_time'] = self.receipt_time
 
         try:
             user = get_publisher().user_class.get(self.user_id)
         except KeyError:
             user = None
-
         # this is custom code so it is possible to mark forms as anonyms, this
         # is done through the VoteAnonymity field, this is very specific but
         # isn't generalised yet into an useful extension mechanism, as it's not
@@ -421,7 +445,6 @@ class FormData(StorableObject):
             if f.key == 'vote-anonymity':
                 user = None
                 break
-
         if user:
             data['user'] = {'id': user.id, 'name': user.display_name}
 
@@ -433,35 +456,7 @@ class FormData(StorableObject):
             else:
                 data['signature'] = {'status': 'missing'}
 
-        data['fields'] = {}
-        for f in self.formdef.fields:
-            if not f.varname:
-                continue
-            if not self.data.has_key(f.id):
-                continue
-
-            value = self.data[f.id]
-
-            if value is None:
-                value = ''
-
-            if not hasattr(f, str('get_view_value')):
-                continue
-
-            if type(value) is str:
-                value = unicode(value, get_publisher().site_charset)
-            elif type(value) in (unicode, bool, int, type(None), list, tuple, dict):
-                pass
-            else:
-                value = f.get_view_value(value)
-            data['fields'][f.varname] = value
-            if f.store_display_value and ('%s_display' % f.id) in self.data:
-                data['fields'][f.varname + '_raw'] = data['fields'][f.varname]
-                display_value = self.data['%s_display' % f.id]
-                if display_value is not None:
-                    if type(display_value) is str:
-                        display_value = unicode(display_value, get_publisher().site_charset)
-                    data['fields'][f.varname] = unicode(display_value)
+        data['fields'] = get_json_dict(self.formdef.fields, self.data)
 
         data['workflow'] = {}
         wf_status = self.get_visible_status()
@@ -470,7 +465,9 @@ class FormData(StorableObject):
         if self.workflow_data:
             data['workflow']['data'] = self.workflow_data
 
-        return json.dumps(data)
+        return json.dumps(data,
+                cls=JSONEncoder,
+                encoding=get_publisher().site_charset)
 
 
     # don't pickle _formdef cache
diff --git a/wcs/wf/form.py b/wcs/wf/form.py
index 08abd1b..28b7ec8 100644
--- a/wcs/wf/form.py
+++ b/wcs/wf/form.py
@@ -22,7 +22,7 @@ from wcs.workflows import WorkflowStatusItem, register_item_class, \
 from wcs.formdef import FormDef
 
 from wcs.admin.fields import FieldWidget, FieldDefPage, FieldsDirectory
-from wcs.formdata import get_dict_with_varnames
+from wcs.formdata import get_json_dict
 
 
 class WorkflowFormFieldsFormDef(FormDef):
@@ -98,7 +98,7 @@ class FormWorkflowStatusItem(WorkflowStatusItem):
     def submit_form(self, form, formdata, user, evo):
         if form.get_submit() == 'submit' and not form.has_errors():
             workflow_data = {}
-            for k, v in get_dict_with_varnames(
+            for k, v in get_json_dict(
                             self.formdef.fields, self.formdef.get_data(form)).items():
                 workflow_data['%s_%s' % (self.varname, k)] = v
             formdata.update_workflow_data(workflow_data)
