ASP .Net - Entity Framework - MobileAppService - 将实体对象推送到后端时出错
ASP .Net - Entity Framework - MobileAppService - Error in pushing entity object to backend
我正在使用 Xamarin 中的离线同步功能在我的移动应用程序和托管在 Azure 上的 MobileAppService 之间同步数据。
我使用了 Entity Framework (V6.1.3),使用 visual studio 包管理器使用代码优先迁移创建了我的数据库。数据库是 Microsoft SQL 服务器,托管在 Azure 上。
当我使用离线同步时,数据插入数据库没有问题。但是当我直接调用网络api并在JSON中发送一个对象时,服务器在执行InserAsync
时抛出一个未知异常(我将调试器连接到MobileAppService 运行上Azure 找出导致问题的命令):
Exception thrown: 'System.Web.Http.HttpResponseException' in mscorlib.dll
api端点代码简单如下:
public async Task<IHttpActionResult> PostUser([FromBody] User item)
{
User current = await InsertAsync(item);
return CreatedAtRoute("Tables", new { id = current.Id , CreatedAt = System.DateTime.Now }, current);
}
这就是我在 Xamarin 客户端中调用 api 的方式:
var JsonContent = JsonConvert.SerializeObject(user);
var httpContent = new StringContent(JsonContent, System.Text.Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync("tables/User/PostUser", httpContent);
令人震惊的是,如果我使用邮递员调用同一个 api 入口点,一切正常。我很困惑,想不出任何其他问题的根源。
我捕获了网络抛出的异常 api 并检查了值。这是手表 window 在远程调试模式下的屏幕截图:
错误可能与 AzureVersion 的值有关,但我不知道如何修复它,因为请求消息的版本设置为 1.1(与调用 api通过邮递员)。
根据你的描述,我检查了Microsoft.Azure.Mobile.Server.dll
中的InsertAsync
方法,我发现这个错误可能是由几个异常引起的(例如DbEntityValidationException, DbUpdateConcurrencyException, DbUpdateException等。 ) 将数据保存到数据库时。为了定位这个问题,您需要捕获详细的错误消息,您可以按照以下方法:
- 使用Fiddler从响应中捕获详细错误如下:
- Remote debug 您的网络应用程序,您可以用
try-catch
包装 InsertAsync
以捕获详细错误,如下所示:
综上所述,您可以尝试定位具体错误并解决。或者您可以提供有关此问题的更详细的错误信息,以便我们找到它。
问题源于使用 AppServiceHelpers.Models.EntityData
,它作为 NuGet 包安装。我的实体都继承自 EntityData
,它为实体添加了一些属性,其中之一是 AzureVersion
:
public class EntityData
{
...
[Version]
public string AzureVersion { get; set; }
}
AzureVersion 标记有属性 [Version]
(Microsoft.WindowsAzure.MobileServices.Version
)。但是JsonConvert
并没有实现这个属性,而是在序列化对象中给这个属性赋了名字AzureVersion
(而不是Version
),这个在MobileServiceContext中并没有定义后端。
为了解决这个问题,我定义了自己的 EntityData 助手 class,并将 属性 名称显式分配给 Version
:
public class MyEntityData
{
[Version]
[JsonProperty(PropertyName = "Version")]
public string AzureVersion { get; set; }
}
如果没有此解决方法,上下文仅适用于 OfflineSync;因为,Version
属性是由MobileServiceClient.SyncContext
实现的,对象存储在本地SQLStore中,属性正确设置为Version
,然后推送到后端如下SyncContext.PushAsync()
。但是,如果您直接将对象推送到后端,属性 将包含 AzureVersion
.
的未识别名称
我正在使用 Xamarin 中的离线同步功能在我的移动应用程序和托管在 Azure 上的 MobileAppService 之间同步数据。
我使用了 Entity Framework (V6.1.3),使用 visual studio 包管理器使用代码优先迁移创建了我的数据库。数据库是 Microsoft SQL 服务器,托管在 Azure 上。
当我使用离线同步时,数据插入数据库没有问题。但是当我直接调用网络api并在JSON中发送一个对象时,服务器在执行InserAsync
时抛出一个未知异常(我将调试器连接到MobileAppService 运行上Azure 找出导致问题的命令):
Exception thrown: 'System.Web.Http.HttpResponseException' in mscorlib.dll
api端点代码简单如下:
public async Task<IHttpActionResult> PostUser([FromBody] User item)
{
User current = await InsertAsync(item);
return CreatedAtRoute("Tables", new { id = current.Id , CreatedAt = System.DateTime.Now }, current);
}
这就是我在 Xamarin 客户端中调用 api 的方式:
var JsonContent = JsonConvert.SerializeObject(user);
var httpContent = new StringContent(JsonContent, System.Text.Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync("tables/User/PostUser", httpContent);
令人震惊的是,如果我使用邮递员调用同一个 api 入口点,一切正常。我很困惑,想不出任何其他问题的根源。
我捕获了网络抛出的异常 api 并检查了值。这是手表 window 在远程调试模式下的屏幕截图:
错误可能与 AzureVersion 的值有关,但我不知道如何修复它,因为请求消息的版本设置为 1.1(与调用 api通过邮递员)。
根据你的描述,我检查了Microsoft.Azure.Mobile.Server.dll
中的InsertAsync
方法,我发现这个错误可能是由几个异常引起的(例如DbEntityValidationException, DbUpdateConcurrencyException, DbUpdateException等。 ) 将数据保存到数据库时。为了定位这个问题,您需要捕获详细的错误消息,您可以按照以下方法:
- 使用Fiddler从响应中捕获详细错误如下:
- Remote debug 您的网络应用程序,您可以用
try-catch
包装InsertAsync
以捕获详细错误,如下所示:
综上所述,您可以尝试定位具体错误并解决。或者您可以提供有关此问题的更详细的错误信息,以便我们找到它。
问题源于使用 AppServiceHelpers.Models.EntityData
,它作为 NuGet 包安装。我的实体都继承自 EntityData
,它为实体添加了一些属性,其中之一是 AzureVersion
:
public class EntityData
{
...
[Version]
public string AzureVersion { get; set; }
}
AzureVersion 标记有属性 [Version]
(Microsoft.WindowsAzure.MobileServices.Version
)。但是JsonConvert
并没有实现这个属性,而是在序列化对象中给这个属性赋了名字AzureVersion
(而不是Version
),这个在MobileServiceContext中并没有定义后端。
为了解决这个问题,我定义了自己的 EntityData 助手 class,并将 属性 名称显式分配给 Version
:
public class MyEntityData
{
[Version]
[JsonProperty(PropertyName = "Version")]
public string AzureVersion { get; set; }
}
如果没有此解决方法,上下文仅适用于 OfflineSync;因为,Version
属性是由MobileServiceClient.SyncContext
实现的,对象存储在本地SQLStore中,属性正确设置为Version
,然后推送到后端如下SyncContext.PushAsync()
。但是,如果您直接将对象推送到后端,属性 将包含 AzureVersion
.