Я выполняю исследовательскую задачу по интеграции стороннего API Authorize.Net. Я написал небольшое консольное приложение, нажал на API и успешно получил сообщение 200. Странно то, что ответ отображается в переменной метода, все, что мне нужно, есть, но на Swagger/Postman я не получаю обратно тело ответа. Мне это на самом деле не нужно, ответ есть в методе, и я могу сохранить нужные мне данные, но я считаю, что как Dev мы всегда должны учиться, и это поставило меня в тупик.
[HttpPost("ChargeCreditCard")]
public async Task < ActionResult > ChargeCreditCard(ChargeCreditCard data)
{
var result = await CreditCardService.Run(data);
return Ok(result);
}
public class CreditCardService {
public async static Task < ANetApiResponse > Run(ChargeCreditCard data) {
ApiOperationBase < ANetApiRequest, ANetApiResponse > .RunEnvironment = AuthorizeNet.Environment.SANDBOX;
// define the merchant information (authentication / transaction id)
ApiOperationBase < ANetApiRequest, ANetApiResponse > .MerchantAuthentication = new merchantAuthenticationType() {
name = data.ApiLoginID,
ItemElementName = ItemChoiceType.transactionKey,
Item = data.ApiTransactionKey,
};
var creditCard = new creditCardType {
cardNumber = "4111111111111111",
expirationDate = "1028",
cardCode = "123"
};
var billingAddress = new customerAddressType {
firstName = "John",
lastName = "Doe",
address = "123 My St",
city = "OurTown",
zip = "98004"
};
//standard api call to retrieve response
var paymentType = new paymentType {
Item = creditCard
};
// Add line Items
var lineItems = new lineItemType[2];
lineItems[0] = new lineItemType {
itemId = "1", name = "t-shirt", quantity = 2, unitPrice = new Decimal(15.00)
};
lineItems[1] = new lineItemType {
itemId = "2", name = "snowboard", quantity = 1, unitPrice = new Decimal(450.00)
};
var transactionRequest = new transactionRequestType {
transactionType = transactionTypeEnum.authCaptureTransaction.ToString(), // charge the card
amount = data.Amount,
payment = paymentType,
billTo = billingAddress,
lineItems = lineItems
};
var request = new createTransactionRequest {
transactionRequest = transactionRequest
};
// instantiate the controller that will call the service
var controller = new createTransactionController(request);
controller.Execute();
// get the response from the service (errors contained if any)
var response = controller.GetApiResponse();
// validate response
if (response != null) {
if (response.messages.resultCode == messageTypeEnum.Ok) {
if (response.transactionResponse.messages != null) {
Console.WriteLine("Successfully created transaction with Transaction ID: " + response.transactionResponse.transId);
Console.WriteLine("Response Code: " + response.transactionResponse.responseCode);
Console.WriteLine("Message Code: " + response.transactionResponse.messages[0].code);
Console.WriteLine("Description: " + response.transactionResponse.messages[0].description);
Console.WriteLine("Success, Auth Code : " + response.transactionResponse.authCode);
} else {
Console.WriteLine("Failed Transaction.");
if (response.transactionResponse.errors != null) {
Console.WriteLine("Error Code: " + response.transactionResponse.errors[0].errorCode);
Console.WriteLine("Error message: " + response.transactionResponse.errors[0].errorText);
}
}
} else {
Console.WriteLine("Failed Transaction.");
if (response.transactionResponse != null &&
response.transactionResponse.errors != null) {
Console.WriteLine("Error Code: " +
response.transactionResponse.errors[0].errorCode);
Console.WriteLine("Error message: " +
response.transactionResponse.errors[0].errorText);
} else {
Console.WriteLine("Error Code: " +
response.messages.message[0].code);
Console.WriteLine("Error message: " +
response.messages.message[0].text);
}
}
} else {
Console.WriteLine("Null Response.");
}
return response;
}
}
Тело ответа в методе:
message [messagesTypeMessage[]]:
{AuthorizeNet.Api.Contracts.V1.messagesTypeMessage[1]}
[0]:
{AuthorizeNet.Api.Contracts.V1.messagesTypeMessage}
code [string]:
"I00001"
text [string]:
"Successful."
Non-Public members
resultCode [messageTypeEnum]:
Ok
Non-Public members
profileResponse [createProfileResponse]:
null
refId [string]:
null
sessionToken [string]:
null
transactionResponse:
{AuthorizeNet.Api.Contracts.V1.transactionResponse}
accountNumber [string]:
"XXXX1111"
accountType [string]:
"Visa"
authCode [string]:
"HTBIYF"
avsResultCode [string]:
"Y"
Ответ возвращается в Swagger
Я использую .Net 7





Похоже, что классы, которые вы используете из Authorize.Net, имеют Fields, но не Properties, и есть конфигурация по умолчанию для исключения полей из сериализации в Asp.Net Core. По умолчанию сериализация выполняется только для свойств.
Чтобы включить поддержку полей:
В вашем файле Program.cs после AddControllers (или AddControllersWithViews - в зависимости от того, является ли это веб-API или веб-приложением) используйте расширение AddJsonOptions, чтобы настроить JsonSerializer для включения следующих полей:
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.IncludeFields = true;
});
В целом, в качестве хорошей практики, которую я принял, я бы рекомендовал использовать AutoMapper для сопоставления объектов с пользовательскими классами или сопоставлять их вручную. Я всегда избегаю возвращать тот же объект в исходной форме, как это было дано в ответе от третьего лица.
Очень интересно! Никогда не думал о проблеме таким образом, спасибо за знание.
Какую версию .net вы используете?