Steps to reproduce:
- Open MainDemo and add the following property to the Contact class:
C#public class Contact : Person, IMapsMarker {
//
private Image propertyName;
[ValueConverter(typeof(DevExpress.Xpo.Metadata.ImageValueConverter))]
public Image PropertyName {
get {
return propertyName;
}
set {
SetPropertyValue(nameof(PropertyName), ref propertyName, value);
}
}
}
// It fails with delayed properties too.
[Delayed(true)]
[ValueConverter(typeof(DevExpress.Xpo.Metadata.ImageValueConverter))]
public Image PropertyNameDelayed {
get {
return GetDelayedPropertyValue<Image>(nameof(PropertyNameDelayed));
}
set {
SetDelayedPropertyValue<Image>(nameof(PropertyNameDelayed), value);
}
}
- Run the demo, open some Contact_DetailView and try to upload a JPEG or JPG image.
Important notes and workarounds
From v14.2, Image Property Editors (both WinForms and ASP.NET) support images saved as byte array objects (in addition to previously supported System.Drawing.Image objects). This allows us to significantly decrease web server memory consumption because the byte array can contain an image in a compressed format and the server does not have to unpack it. The previous approach with the System.Drawing.Image type property is still supported, but we recommend that you migrate to the byte array storage to improve performance. Refer to the BLOB Image Properties in XPO and How to change the image property type from System.Drawing.Image to byte array help topics for more details.
Actual Behavior:
The image is not uploaded and ExternalException is thrown when you try to save the object.
The error occurred:
Type: ExternalException
Message: A generic error occurred in GDI+.
Data: 0 entries
Stack trace:
at System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams)
at System.Drawing.Image.Save(MemoryStream stream)
at System.Drawing.ImageConverter.ConvertTo(ITypeDescriptorContext context, CultureInfo culture, Object value, Type destinationType)
at DevExpress.Xpo.Metadata.ImageValueConverter.ConvertToStorageType(Object value)
at DevExpress.Xpo.Generators.BaseObjectQueryGenerator.GetMemberParameter(XPMemberInfo member, Object theObject)
at DevExpress.Xpo.Generators.BaseObjectQueryGenerator.BuildFieldList()
at DevExpress.Xpo.Generators.UpdateQueryGenerator.InternalGenerateSql(CriteriaOperator criteria)
at DevExpress.Xpo.Generators.BaseQueryGenerator.GenerateSql(CriteriaOperator criteria)
at DevExpress.Xpo.Generators.BaseObjectQueryGenerator.GenerateSql(ObjectGeneratorCriteriaSet criteriaSet, MemberInfoCollection properties, Boolean reverse)
at DevExpress.Xpo.Generators.UpdateQueryGenerator.GenerateUpdate(XPDictionary dictionary, BatchWideDataHolder4Modification batchWideData, Object theObject, MemberInfoCollection properties, ObjectGeneratorCriteriaSet criteriaSet)
at DevExpress.Xpo.Helpers.ProcessingSave.InternalUpdateObject(List`1 updateList, Object theObject)
at DevExpress.Xpo.Helpers.ProcessingSave.Process()
at DevExpress.Xpo.SimpleObjectLayer.BeginCommitChangesInsideTransaction(CommitChangesContext context, ICollection fullListForDelete, ICollection completeListForSave)
at DevExpress.Xpo.SimpleObjectLayer.CommitChanges(Session session, ICollection fullListForDelete, ICollection completeListForSave)
at DevExpress.Xpo.Session.FlushChangesInsideTransaction()
at DevExpress.Xpo.Session.FlushChanges()
at DevExpress.Xpo.SessionObjectLayer.CommitChanges(Session session, ICollection fullListForDelete, ICollection completeListForSave)
at DevExpress.Xpo.Session.FlushChangesInsideTransaction()
at DevExpress.Xpo.Session.FlushChanges()
at DevExpress.Xpo.Session.<CommitTransaction>b__55()
at DevExpress.Xpo.Logger.LogManager.Log(String category, LogHandlerVoid handler, MessageHandler`1 createMessageHandler, ExceptionHandler exceptionHandler)
at DevExpress.Xpo.Session.CommitTransaction()
at DevExpress.Xpo.UnitOfWork.CommitChanges()
at DevExpress.ExpressApp.Xpo.XPObjectSpace.DoCommit()
at DevExpress.ExpressApp.BaseObjectSpace.CommitChanges()
at DevExpress.ExpressApp.Web.SystemModule.WebModificationsController.Save(SimpleActionExecuteEventArgs args)
at DevExpress.ExpressApp.SystemModule.ModificationsController.saveAction_OnExecute(Object sender, SimpleActionExecuteEventArgs e)
at DevExpress.ExpressApp.Actions.SimpleAction.RaiseExecute(ActionBaseEventArgs eventArgs)
at DevExpress.ExpressApp.Actions.ActionBase.ExecuteCore(Delegate handler, ActionBaseEventArgs eventArgs)
InnerException is null
Expected Behavior:
The image is uploaded successfully.