我正在使用Azure Cosmos DB作为持久性存储的ASP.Net Core 3.0 API。这是我第一次使用Cosmos DB。当我尝试创建新项目(文档)时,我收到了邮递员中的错误消息,提示...
"Response status code does not indicate success: 400 Substatus: 0
Reason: (Message: {\"Errors\":[\"The input name '{' is invalid.
Ensure to provide a unique non-empty string less than '1024' characters."
我不知道是什么原因引起的。
我在我的项目中使用Microsoft.Azure.Cosmos v3.4.0 nuget
这是我的存储库中用于添加新帐户文档的方法。
public async Task AddAccountAsync(Account account)
{
await _container.CreateItemAsync(account, new PartitionKey(account.Id));
}
在调试模式下,当我将鼠标悬停在“ Account account”对象上时,这里是属性值的图片。
我在Cosmos DB中的容器设置为/ id作为分区键。
这是我在邮递员中的请求正文;
{
"id": "00000000-0000-0000-0000-000000000000",
"accountName": "Test Company 1",
"accountType": 1,
"ownerId": "00000000-0000-0000-0000-000000000000",
"isTaxExempt": false,
"mailJobProxyId": "00000000-0000-0000-0000-000000000000",
"salesPersonId": "00000000-0000-0000-0000-000000000000"
}
这是Account类;
public class Account
{
// Aggregate state properties
[JsonProperty(PropertyName = "id")]
public AccountId Id { get; set; }
[JsonProperty(PropertyName = "accountName")]
public AccountName AccountName { get; set; }
[JsonProperty(PropertyName = "accountType")]
public AccountTypes AccountType { get; set; }
[JsonProperty(PropertyName = "ownerId")]
public OwnerId OwnerId { get; set; }
[JsonProperty(PropertyName = "isTaxExempt")]
public bool IsTaxExempt { get; set; }
[JsonProperty(PropertyName = "mailJobProxyId")]
public MailJobProxyId MailJobProxyId { get; set; }
[JsonProperty(PropertyName = "salesPersonId")]
public SalesPersonId SalesPersonId { get; set; }
[JsonProperty(PropertyName = "addresses")]
public List<Address.Address> Addresses { get; set; }
[JsonProperty(PropertyName = "contacts")]
public List<Contact.Contact> Contacts { get; set; }
[JsonProperty(PropertyName = "postagePaymentMethods")]
public List<PostagePaymentMethod.PostagePaymentMethod> PostagePaymentMethods { get; set; }
public Account(string id, string accountName, AccountTypes accountType, string ownerId, Guid mailJobProxyId, Guid salesPersonId, bool isTaxExempt)
{
Id = AccountId.FromString(id);
AccountName = AccountName.FromString(accountName);
AccountType = accountType;
OwnerId = OwnerId.FromString(ownerId);
MailJobProxyId = new MailJobProxyId(mailJobProxyId);
SalesPersonId = new SalesPersonId(salesPersonId);
IsTaxExempt = isTaxExempt;
Addresses = new List<Address.Address>();
Contacts = new List<Contact.Contact>();
PostagePaymentMethods = new List<PostagePaymentMethod.PostagePaymentMethod>();
Status = Status.Active;
}
}
如果您需要其他代码示例,请告诉我。
在美国东部标准时间6:43p更新11/6/19
这是AccountId值对象
public class AccountId : Value<AccountId>
{
public string Value { get; internal set; }
// Parameterless constructor for serialization requirements
protected AccountId() { }
internal AccountId(string value) => Value = value;
// Factory pattern
public static AccountId FromString(string accountId)
{
CheckValidity(accountId);
return new AccountId(accountId);
}
public static implicit operator string(AccountId accountId) => accountId.Value;
private static void CheckValidity(string value)
{
if (!Guid.TryParse(value, out _))
{
throw new ArgumentException(nameof(value), "Account Id is not a GUID.");
}
}
}
这是Startup.cs中的初始化类,用于设置数据库和容器。
private static async Task<AccountsRepository> InitializeCosmosClientAccountInstanceAsync(IConfigurationSection configurationSection)
{
var databaseName = configurationSection.GetSection("DatabaseName").Value;
string uri = configurationSection.GetSection("Uri").Value;
string key = configurationSection.GetSection("Key").Value;
CosmosClientBuilder clientBuilder = new CosmosClientBuilder(uri, key);
CosmosClient client = clientBuilder
.WithConnectionModeDirect()
.Build();
DatabaseResponse database = await client.CreateDatabaseIfNotExistsAsync(databaseName);
string containerName = configurationSection.GetSection("AccountsContainerName").Value;
await database.Database.CreateContainerIfNotExistsAsync(containerName, "/id");
AccountsRepository cosmosDbService = new AccountsRepository(client, databaseName, containerName);
return cosmosDbService;
}
这是发生错误时的堆栈跟踪;
stackTrace": " at Microsoft.Azure.Cosmos.ResponseMessage.EnsureSuccessStatusCode()\r\n
at Microsoft.Azure.Cosmos.CosmosResponseFactory.ToObjectInternal[T]
(ResponseMessage cosmosResponseMessage, CosmosSerializer jsonSerializer)\r\n
at Microsoft.Azure.Cosmos.CosmosResponseFactory.
<CreateItemResponseAsync>b__6_0[T](ResponseMessage cosmosResponseMessage)\r\n
at Microsoft.Azure.Cosmos.CosmosResponseFactory.ProcessMessageAsync[T]
(Task`1 cosmosResponseTask, Func`2 createResponse)\r\n at
Delivery.Api.Infrastructure.AccountsRepository.AddAccountAsync(Account
account) in
C:\\AzureDevOps\\Delivery\\Delivery.Api\\Accounts\\AccountsRepository.cs:line 20\r\n
at Delivery.Api.Accounts.AccountsApplicationService.HandleCreate(Create cmd)
in C:\\AzureDevOps\\Delivery\\Delivery.Api\\Accounts\\AccountsApplicationService.cs:line 43\r\n
at Delivery.Api.Infrastructure.RequestHandler.HandleCommand[T](T request, Func`2 handler, ILogger log)
in C:\\AzureDevOps\\Delivery\\Delivery.Api\\Infrastructure\\RequestHandler.cs:line 16
答案 0 :(得分:2)
您可能需要为AccountId
,OwnerId
等创建自定义转换器。
这是我的考试:
class AccountIdConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(AccountId));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return AccountId.FromString(JToken.Load(reader).ToString());
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JToken.FromObject(value.ToString()).WriteTo(writer);
}
}
添加toString方法,并设置为使用自定义转换器
[JsonConverter(typeof(AccountIdConverter))]
public class AccountId
{
public string Value { get; internal set; }
protected AccountId() { }
internal AccountId(string value) => Value = value;
public static AccountId FromString(string accountId)
{
CheckValidity(accountId);
return new AccountId(accountId);
}
public static implicit operator string(AccountId accountId) => accountId.Value;
public override string ToString()
{
return Value;
}
private static void CheckValidity(string value)
{
if (!Guid.TryParse(value, out _))
{
throw new ArgumentException(nameof(value), "Account Id is not a GUID.");
}
}
}
class Account
{
[JsonProperty(PropertyName = "id")]
public AccountId Id { get; set; }
public Account(string id)
{
Id = AccountId.FromString(id);
}
}
static void Main(string[] args)
{
// Test toString
AccountId accountId = AccountId.FromString(Guid.NewGuid().ToString());
Console.WriteLine(accountId.ToString());
// Test AccountIdConverter
Console.WriteLine(JsonConvert.SerializeObject(accountId));
// Test for serializing Account
Account account = new Account(Guid.NewGuid().ToString());
string accountJson = JsonConvert.SerializeObject(account);
Console.WriteLine(accountJson);
// Test for deserializing Account
Account accountDeserialized = JsonConvert.DeserializeObject<Account>(accountJson);
Console.WriteLine(accountDeserialized.Id);
Console.ReadLine();
}
您会看到包含Account
对象的AccountId
对象可以按预期正确进行序列化和反序列化。