У меня есть приложение Xamarin.Forms (4.7.0.1239) и настраиваемая реализация MVVM.
Intro
Каждая ViewModel имеет void OnPageAppearing () и ICommand NextCommand.
public BaseContentPage<TViewModel> : ContentPage
where TViewModel : BaseViewModel
{
public virtual void OnPageAppearing()
{
ViewModel.OnPageAppearing();
base.OnPageAppearing();
}
// ...
}
public BaseViewModel : INotifyPropertyChanged
{
public virtual OnPageAppearing() { }
}
Когда я вызываю OnPageAppearing()
, я загружаю данные из хранилища (десериализую JSON). Когда я вызываю NextCommand, я сохраняю данные в хранилище (я сериализую для своих моделей).
У меня есть несколько моделей:
public enum ProductAnomaly
{
Missing,
Broken
}
public class Anomaly
{
public string ProductId { get; set; }
[JsonIgnore]
public Product Product { get; set; }
public ProductAnomaly Type { get; set; }
public string PhotoFileName { get; set; }
public string Comment { get; set; }
}
public class Product
{
public string Id { get ; set ; } = Guid.NewGuid().ToString();
public string Description { get; set; }
public string Barcode { get; set; }
public string Barcode2 { get; set; }
public string MissionId { get; set; }
public bool IsValidated { get; set; } = true;
public int DeliveredQuantity { get; set; } = 0;
public bool? WithMounting { get; set; }
public int Quantity { get; set; }
public System.Collections.Generic.HashSet<Anomaly> Anomalies { get; set; }
}
В одной из моих ViewModels я вызываю NextCommand
и я сохраняю данные:
// ReportAnomalyViewModel:
private Product _product;
public Product Product
{
get => _product;
set => SetProperty(ref _product, value);
}
public ICommand NextCommand => new Command(async () =>
{
await DataService.SaveAnomalyToStorage(Product, ProductAnomaly.Missing);
}
// DataService:
public async Task SaveAnomalyToStorage(Product product, ProductActivity productAnomaly)
{
var anomaly = new Anomaly
{
Type = productAnomaly,
Product = product,
ProductId = product.Id,
Comment = comment,
PhotoFileName = photoFileName
}
var json = JsonConvert.SerializeObject(anomaly);
//...
}
... и
[0:] Invoke 'SaveAnomalyToStorageAsync'
08-06 18:57:10.111 I/Choreographer(12422): Skipped 2657 frames! The application may be doing too much work on its main thread.
08-06 18:57:10.128 I/OpenGLRenderer(12422): Davey! duration=44301ms; Flags=0, IntendedVsync=12648113739375, Vsync=12692397070937, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=12692398346460, AnimationStart=12692398374460, PerformTraversalsStart=12692398492660, DrawStart=12692408231060, SyncQueued=12692409579560, SyncStart=12692410445760, IssueDrawCommandsStart=12692410615460, SwapBuffers=12692411988260, FrameCompleted=12692415697560, DequeueBufferDuration=248000, QueueBufferDuration=2886000,
**System.InvalidCastException:** 'Specified cast is not valid.'
Thread finished: <Thread Pool> #12
The thread 0xc has exited with code 0 (0x0).
08-06 18:57:30.089 D/Mono (12422): DllImport attempting to load: '/system/lib/liblog.so'.
08-06 18:57:30.089 D/Mono (12422): DllImport loaded library '/system/lib/liblog.so'.
08-06 18:57:30.089 D/Mono (12422): DllImport searching in: '/system/lib/liblog.so' ('/system/lib/liblog.so').
08-06 18:57:30.089 D/Mono (12422): Searching for '__android_log_print'.
08-06 18:57:30.089 D/Mono (12422): Probing '__android_log_print'.
08-06 18:57:30.089 D/Mono (12422): Found as '__android_log_print'.
08-06 18:57:30.096 I/MonoDroid(12422): UNHANDLED EXCEPTION:
08-06 18:57:30.099 I/MonoDroid(12422): System.InvalidCastException: Specified cast is not valid.
08-06 18:57:30.099 I/MonoDroid(12422): at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonContract valueContract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) [0x000d6] in <2073514815234917a5e8f91b0b239405>:0
08-06 18:57:30.099 I/MonoDroid(12422): at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize (Newtonsoft.Json.JsonWriter jsonWriter, System.Object value, System.Type objectType) [0x00079] in <2073514815234917a5e8f91b0b239405>:0
08-06 18:57:30.099 I/MonoDroid(12422): at Newtonsoft.Json.JsonSerializer.SerializeInternal (Newtonsoft.Json.JsonWriter jsonWriter, System.Object value, System.Type objectType) [0x0023a] in <2073514815234917a5e8f91b0b239405>:0
08-06 18:57:30.099 I/MonoDroid(12422): at Newtonsoft.Json.JsonSerializer.Serialize (Newtonsoft.Json.JsonWriter jsonWriter, System.Object value, System.Type objectType) [0x00000] in <2073514815234917a5e8f91b0b239405>:0
08-06 18:57:30.099 I/MonoDroid(12422): at Newtonsoft.Json.JsonConvert.SerializeObjectInternal (System.Object value, System.Type type, Newtonsoft.Json.JsonSerializer jsonSerializer) [0x00028] in <2073514815234917a5e8f91b0b239405>:0
08-06 18:57:30.099 I/MonoDroid(12422): at Newtonsoft.Json.JsonConvert.SerializeObject (System.Object value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings) [0x00007] in <2073514815234917a5e8f91b0b239405>:0
08-06 18:57:30.099 I/MonoDroid(12422): at Newtonsoft.Json.JsonConvert.SerializeObject (System.Object value) [0x00000] in <2073514815234917a5e8f91b0b239405>:0
08-06 18:57:30.099 I/MonoDroid(12422): at Abc.Mobile.Services.DataService.SaveAnomalyToStorageAsync (Abc.Entities.Product product, Abc.Entities.ProductAnomaly productAnomaly, System.String comment, System.String photoFileName) [0x0006e] in C:\Repos\Abc\src\Abc.Mobile\Services\DataService.cs:326
08-06 18:57:30.099 I/MonoDroid(12422): at Abc.Mobile.ViewModels.ReportAnomalyViewModel.<get_NextCommand>b__35_0 () [0x0022e] in C:\Repos\Abc\src\Abc.Mobile\ViewModels\ReportAnomalyViewModel.cs:100
08-06 18:57:30.099 I/MonoDroid(12422): at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021
08-06 18:57:30.099 I/MonoDroid(12422): at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in <eaa205f580954a64824b74a79fa87c62>:0
08-06 18:57:30.099 I/MonoDroid(12422): at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <eaa205f580954a64824b74a79fa87c62>:0
08-06 18:57:30.099 I/MonoDroid(12422): at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <eaa205f580954a64824b74a79fa87c62>:0
08-06 18:57:30.099 I/MonoDroid(12422): at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.1(intptr,intptr)
пытается
dotnetfiddle
Я пробовал тот же код здесь: https://dotnetfiddle.net/wjlMdW
Работает ...
Другой проект
Мой объект аномалии правильно сериализуется ...
в другом консольном проекте (do tnet core), я сослался на свои модели и попробовал:
static void Main(string[] args)
{
var product = new Product
{
Anomalies = new System.Collections.Generic.HashSet<Anomaly>(),
Barcode = Guid.NewGuid().ToString(),
Barcode2 = Guid.NewGuid().ToString(),
DeliveredQuantity = 0,
Description = Guid.NewGuid().ToString(),
MissionId = Guid.NewGuid().ToString(),
Quantity = 3,
WithMounting = false
};
var anomaly = new Anomaly
{
Type = ProductAnomaly.Missing,
Product = product,
ProductId = product.Id,
Comment = "",
PhotoFileName = ""
};
var json = JsonConvert.SerializeObject(anomaly);
System.Console.WriteLine(json);
System.Console.ReadLine();
}
Результат:
Unhandled exception. System.InvalidCastException: Unable to cast object of type 'Abc.Entities.Anomaly' to type 'System.Collections.IEnumerable'.
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonConvert.SerializeObjectInternal(Object value, Type type, JsonSerializer jsonSerializer)
at Newtonsoft.Json.JsonConvert.SerializeObject(Object value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.SerializeObject(Object value)
at Abc.Console.Program.Main(String[] args) in C:\Repos\Abc\src\Abc.Console\Program.cs:line 33