我正在开发一款应用,现在我被困在我的UWP应用的注册页面。
所以我为我的应用程序创建了一个后端,后端的一些变量是枚举,例如我有一个名为Personal的类,它有一个枚举变量,如公共性别性别{get; set;}那个和枚举,每当我为变量转换为sql Azure中的int变量表。
没有问题,但我的主要问题在于我的客户。 我跟随Adrian Hall Book,所以我在客户端有以下课程:
public class Personal : TableData
{
[Required]
[StringLength(50)]
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[Required]
[StringLength(50)]
[JsonProperty(PropertyName = "dadlastname")]
public string DadLastName { get; set; }
[Required]
[StringLength(50)]
[JsonProperty(PropertyName = "momlastname")]
public string MomLastName { get; set; }
[Required]
[StringLength(50)]
[JsonProperty(PropertyName = "email")]
public string Email { get; set; }
[Required]
[JsonProperty(PropertyName = "sex")]
public Gender Sex { get; set; }//ENUM TYPE
[Required]
[Column(TypeName = "date")]
[JsonProperty(PropertyName = "birthdate")]
public DateTime? BirthDate { get; set; }
public override bool Equals(object obj)
{
return Equals<Personal>(obj, this);
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
}
你可以看到这是我的枚举:
public enum Gender : Int32
{
[Display(Name = "EnumGenderMale")]
Male = 0,
[Display(Name = "EnumGenderFemale")]
Female = 1
}
我知道enum默认继承自Int32,但是我试图让这个工作,所以每次我初始化我的后备存储时它会创建我的sqllite.db但根据我的日志记录的枚举类型被创建为类型[TEXT因此,每当我尝试在我的后端写入时,它会抛出HTTPStatusCode:500内部服务器错误,并且它不会在我的sqlazure数据库上写任何内容。
我猜测它的主要问题是因为我使用枚举它是最好的做法,以便在客户端使用枚举并能够在我的后端写入?
我的错误是在我的pushasync方法中引发的,这是我的同步类的类:
public async Task SyncOfflineCacheAsync()
{
await InitializeAsync();
try
{
await client.SyncContext.PushAsync();
}
catch (MobileServicePushFailedException ex)
{
if(ex.PushResult != null)
{
foreach (var error in ex.PushResult.Errors)
{
var objString = error.Item.ToString();
await ResolveAnyConflictAsync(error, objString);
}
}
}
catch(Exception ex)
{
Debug.WriteLine($"Database corrupted, purging database: {ex.Message}");
//purge database
}
//Pull each sync table
var accountTable = await GetSyncTableAsync<Account>();
await accountTable.PullAsync();
var personalTable = await GetSyncTableAsync<Personal>();
await personalTable.PullAsync();
var laborTable = await GetSyncTableAsync<Labor>();
await laborTable.PullAsync();
var subscriptionTable = await GetSyncTableAsync<Subscription>();
await subscriptionTable.PullAsync();
}
public async Task InitializeAsync()
{
//Short circuit to database if its already initialized.
if(client.SyncContext.IsInitialized)
{
Debug.WriteLine($"InitializedAsync: Short Circuit");
return;
}
//create a reference to the local sqlLite store.
Debug.WriteLine("InitializeAsync: Initializing store");
var store = new MobileServiceSQLiteStoreWithLogging("ceneam.db", true, true);
//Define Database Schema
store.DefineTable<Account>();
store.DefineTable<Personal>();
store.DefineTable<Labor>();
store.DefineTable<Subscription>();
//Actually create the store and update the schema.
Debug.WriteLine("InitializeAsync: Initializing SyncContext");
await client.SyncContext.InitializeAsync(store);
//Do the sync
Debug.WriteLine("InitializeAsync: Syncing Ceneam Offline Cache");
await SyncOfflineCacheAsync();
}
public static async Task ResolveAnyConflictAsync(MobileServiceTableOperationError error, string objString)
{
switch (GetModelErrorType(objString))
{
case "Account":
{
await ResolvePushConflictAsync<Account>(error);
break;
}
case "Personal":
{
await ResolvePushConflictAsync<Personal>(error);
break;
}
case "Labor":
{
await ResolvePushConflictAsync<Labor>(error);
break;
}
case "Subscription":
{
await ResolvePushConflictAsync<Subscription>(error);
break;
}
}
}
static async Task ResolvePushConflictAsync<T>(MobileServiceTableOperationError error) where T : TableData
{
Debug.WriteLine($"Resolve conflict for {error.Item}");
var serverItem = error.Result.ToObject<T>();
var localItem = error.Item.ToObject<T>();
// Note that you need to implement the public override Equals(TableModel item)
// method in the Model for this to work
if(serverItem.Equals(localItem))
{
//Items are the same, so ignore the conflict
await error.CancelAndDiscardItemAsync();
return;
}
//Client wins
localItem.Version = serverItem.Version;
await error.UpdateOperationAsync(JObject.FromObject(localItem));
//Server wins
//await error.CancelAndDiscardItemAsync();
}
所以这些课程在Adrian Hall的书籍中展示和教授,我已经应用了我自己的那本书。在adrian halls的例子中,我只使用布尔和文本,我可以毫无错误地同步我的数据库我猜测它失败了,因为我使用枚举,有人可以指出我正确的方向如何在使用Azure移动应用程序时处理枚举,因为即使我摆脱了脱机支持(sqlLite存储),它仍然失败并且我不断收到错误代码500.
答案 0 :(得分:1)
根据操作说明,我在我这边检查了这个问题,并在天蓝色门户网站上的快速启动刀片上查看了Download and run the client project和服务器项目。它可以在我的本地工作,你可以参考我的测试如下:
服务器型号:
public class ToDoItem : EntityData
{
public string Text { get; set; }
public bool Complete { get; set; }
public Gender Sex { get; set; }
}
public enum Gender
{
[Display(Name = "EnumGenderMale")]
Male = 0,
[Display(Name = "EnumGenderFemale")]
Female = 1
}
客户端型号:
public class TodoItem
{
public string Id { get; set; }
[JsonProperty(PropertyName = "text")]
public string Text { get; set; }
[JsonProperty(PropertyName = "sex")]
public Gender Sex { get; set; }
}
public enum Gender
{
[Display(Name = "EnumGenderMale")]
Male = 0,
[Display(Name = "EnumGenderFemale")]
Female = 1
}
通过浏览器访问数据:
客户端应用
添加新记录,检查本地sqlite商店:
调用await App.MobileService.SyncContext.PushAsync();
,使用fiddler捕获网络跟踪,如下所示:
有人可以指出我在使用Azure移动应用程序时如何处理枚举的正确方向,因为即使我摆脱了脱机支持(sqlLite存储)它仍然失败并且我不断收到错误代码500.
在移动应用项目的config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
文件下配置Startup.MobileApp.cs
以捕获详细的错误消息。此外,您可以参考here调试移动应用后端。