#c# #json #asp.net-web-api #anonymous-types
#c# #json #asp.net-web-api #анонимные типы
Вопрос:
У меня есть служба Windows, которая имеет следующий код
public class CertificationStatusCheckJob : IJob
{
public readonly ILog _logger = LogManager.GetCurrentClassLogger();
readonly HttpClient client = new HttpClient { BaseAddress = new Uri(ConfigurationManager.AppSettings["MercuryServicesWebApiUrl"]) };
// Temporary local versoin of statuses
private enum CertificationStatus
{
Active = 1,
Pending,
PendingRenewal,
RenewalPastDue,
ReinstatementOnCurrentCycle,
ClosedInactive,
ClosedRenewed
};
public async void Execute(IJobExecutionContext context)
{
Dictionary<string, int> designationWindows = new Dictionary<string, int>
{
{"RenewalWindow", 10},
{"CertificationLength", 12},
{"FreeGrace", 1},
{"InactiveAccessLength",1},
{"InactivityLength", 36}
};
Console.WriteLine("CertificationApplicationStatusCheckJob: Creating Cert application status job");
string content = null;
List<Certification> retrievedCerts = null;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Call webapi to retrieve all applications
var certificationsResponse = client.GetAsync("certifications/getAllCertifications").Resu<
// loop through all applications and compare to rules
if (certificationsResponse.IsSuccessStatusCode)
{
content = certificationsResponse.Content.ReadAsStringAsync().Resu<
Console.WriteLine(content);
}
if (content != null)
{
retrievedCerts = JsonConvert.DeserializeObject<List<Certification>>(content);
_logger.Debug("Got Certifications OK");
}
// Allows for all task calls to service api to be performed in parallel in async
if (retrievedCerts != null)
await Task.WhenAll(retrievedCerts.Select(i => CheckCert(i)) as IEnumerable<Task>);
}
private async Task<object> CheckCert(Certification cert)
{
// current date time to compare the range for each state below to.
// if this date falls in the range for the state, do not change the state,
// otherwise kick them into the next state.
DateTime currentDateTime = DateTime.UtcNow;
var newCertStatus = new { certUniqueId = Guid.NewGuid(), statusId=6 };
switch ((CertificationStatus)cert.CertificationStatusId)
{
case CertificationStatus.Active:
//Condition to test for when the cert is in the active state
await client.PostAsJsonAsync("certifications/updateStateForCertification", newCertStatus);
break;
case CertificationStatus.Pending:
break;
case CertificationStatus.PendingRenewal:
break;
case CertificationStatus.RenewalPastDue:
break;
case CertificationStatus.ReinstatementOnCurrentCycle:
break;
case CertificationStatus.ClosedInactive:
break;
case CertificationStatus.ClosedRenewed:
break;
}
return null;
}
}
Ниже приведены службы, которые вызываются
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary> Gets all certifications. </summary>
/// <returns> all certifications. </returns>
////////////////////////////////////////////////////////////////////////////////////////////////////
[Route("getAllCertifications")]
[AllowAnonymous]
public async Task<List<Certification>> GetAllCertifications()
{
List<Certification> certList = null;
try
{
certList = await _certificationService.GetAllCertifications();
}
catch (Exception e)
{
_logger.Error("exception GetAllCertifications", e);
throw;
}
return certList;
}
//TODO WRITE SERVICE ENTRY POINT FOR SAVE ROUTINE
[Route("updateStateForCertification")]
[AcceptVerbs("POST")]
[AllowAnonymous]
public void UpdateStateForCertification(Guid certUniqueId, int statusId)
{
List<Certification> certList = null;
try
{
_certificationService.UpdateStateForCertification(certUniqueId, statusId);
}
catch (Exception e)
{
_logger.Error("exception UpdateStateForCertification", e);
throw;
}
}
}
Я проверил, что вызов GetAsync GetAllCertifications() работает, поскольку я могу выполнять отладку в этом блоке кода. Однако, когда я выполняю PostAsJsonAsync с использованием анонимного типа, это не сработает. Я знаю, что json заботится только о свойствах. Я также проверил, что он попадает в строку кода PostAsJsonAsync, поэтому он должен выполнять post. Итак, что я делаю не так?
Комментарии:
1. Можете ли вы попробовать перейти
content = certificationsResponse.Content.ReadAsStringAsync().Result
наcontent = await certificationsResponse.Content.ReadAsStringAsync()
? Это что-нибудь меняет?2. @avo — GetAllCertifications работает нормально… это сообщение, которое не
Ответ №1:
проблема в вашем методе веб-api. Ваш метод post принимает два «простых» типа. И по умолчанию простые типы считываются из URI, А НЕ из тела.
Тело считывается для сложного типа. Итак, у вас есть два варианта:
- Сделайте параметр в вашем методе web api сложным типом с соответствующими свойствами
- Поместите свои параметры в свой URI, чтобы получить их
Вы не можете прочитать два примитивных типа из тела, вы можете только принудительно прочитать один из них с [FromBody]
помощью атрибута.
Более подробно вы можете ознакомиться с привязкой параметров здесь: Привязка параметров в ASP.NET Веб — API