We have a Blazor front end app that uses a C# service layer and repository patterned ASP.NET Core Web API.
When trying to make a POST request to one of the controllers, I only get a 400 "Bad Request" returned. I cannot get a breakpoint to hit in the API controller method and I cannot seem to view the request before it is being sent.
I'm using VS 2022
The initial service call:
await IssueHoldService.CreateIssueHold(issueHold);
The service method:
public async Task<Warrant> CreateIssueHold(Warrant warrant)
{
var warrantJson = new StringContent(JsonSerializer.Serialize(warrant), Encoding.UTF8, "application/json");
string x = warrantJson.ToString();
var response = await _httpClient.PostAsync("api/IssueHold", warrantJson);
Warrant result = null;
if (response.IsSuccessStatusCode)
{
result = await JsonSerializer.DeserializeAsync<Warrant>(await response.Content.ReadAsStreamAsync());
}
return result;
}
This response returns:
StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{
Transfer-Encoding: chunked
Server: Microsoft-IIS/10.0
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcMzIzNjA2XHNvdXJjZVxFZ2lkLlJlY29uXEVnaWQuUmVjb24uQXBpXGFwaVxJc3N1ZUhvbGQ=?=
Persistent-Auth: true
X-Powered-By: ASP.NET
Date: Tue, 13 Jun 2023 18:11:39 GMT
Content-Type: application/problem+json; charset=utf-8
}
The API controller method:
[HttpPost]
public async Task<IActionResult> Create([FromBody] Warrant warrant)
{
if (warrant == null)
return BadRequest();
if (!ModelState.IsValid)
return BadRequest(ModelState);
try
{
var newId = await _issueHoldRepository.CreateAsync(warrant);
var createdWarrant = await _issueHoldRepository.GetByIdAsync(newId);
return Created("warrant", createdWarrant);
}
catch
{
return BadRequest();
}
}
The repository method:
public async Task<int> CreateAsync(Warrant entity)
{
System.Diagnostics.Debugger.Break();
string sql = @"INSERT INTO [dbo].[IssueHold]
([CheckNumber]
,[IssueSuffix]
,[ControlNumber]
,[AgencyNumber]
,[Name]
,[SSN]
,[Addr1]
,[Addr2]
,[City]
,[St]
,[Zip]
,[Reason]
,[DateIssued]
,[IssuedBy]
,[AmountPaid]
,[AmountDue]
,[RefundAmount]
,[ClaimNumber]
,[DateMailed]
,[DateCreated]
,[CreatedBy]
,[PrintIssue]
,[PrintAmount]
,[Beneficiary]
,[WarrantType]
,[Void]
,[DateRequested]
,[OrigCheckNum])
OUTPUT Inserted.HoldKey
VALUES
(@CheckNumber
, @IssueSuffix
, @ControlNumber
, @AgencyNumber
, @Name
, @SSN
, @Addr1
, @Addr2
, @City
, @St
, @Zip
, @Reason
, @DateIssued
, @IssuedBy
, @AmountPaid
, @AmountDue
, @RefundAmount
, @ClaimNumber
, @DateMailed
, @DateCreated
, @CreatedBy
, @PrintIssue
, @PrintAmount
, @Beneficiary
, @WarrantType
, @Void
, @DateRequested
, @OrigCheckNum)";
try
{
using (var connection = CreateConnection())
{
return (await connection.ExecuteScalarAsync<int>(sql, entity));
}
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
}
How can I view the actual request to see what might be malformed? I've tried putting a console log in the !ModelState.IsValid portion of the API controller but it never logs anything.
Any ideas?
Here is the DB Table where the SQL is trying to insert
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Egid.Recon.Shared.Entities
{
public class Warrant : EntityBase
{
public int HoldKey { get; set; }
[MaxLength(10)]
public string CheckNumber { get; set; }
[MaxLength(2)]
public string IssueSuffix { get; set; }
[MaxLength(10)]
public string ControlNumber { get; set; }
[MaxLength(10)]
public string AgencyNumber { get; set; }
[MaxLength(60)]
public string Name { get; set; }
[MaxLength(9)]
public string SSN { get; set; }
[MaxLength(50)]
public string Addr1 { get; set; }
[MaxLength(50)]
public string Addr2 { get; set; }
[MaxLength(30)]
public string City { get; set; }
[MaxLength(2)]
public string St { get; set; }
[MaxLength(10)]
public string Zip { get; set; }
public string Reason { get; set; }
public DateTime? DateIssued { get; set; }
[MaxLength(15)]
public string IssuedBy { get; set; }
//[RegularExpression(@"^\$?\-?([1-9]{1}[0-9]{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))$|^\-?\$?([1-9]{1}\d{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))$|^\(\$?([1-9]{1}\d{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))\)$", ErrorMessage = "Invalid Amount. Please use the format of XXXX.XX.")]
public decimal AmountPaid { get; set; }
public string AmountPaidDisplay
{
get { return String.Format("{0:C2}", AmountPaid); }
}
//[RegularExpression(@"^\$?\-?([1-9]{1}[0-9]{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))$|^\-?\$?([1-9]{1}\d{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))$|^\(\$?([1-9]{1}\d{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))\)$", ErrorMessage = "Invalid Amount. Please use the format of XXXX.XX.")]
public decimal AmountDue { get; set; }
public string AmountDueDisplay
{
get { return String.Format("{0:C2}", RefundAmount); }
}
public decimal RefundAmount { get; set; }
public string RefundAmountDisplay
{
get { return String.Format("{0:C2}", RefundAmount); }
}
[MaxLength(15)]
public string ClaimNumber { get; set; }
public DateTime? DateMailed { get; set; }
public DateTime? DateCreated { get; set; }
[MaxLength(15)]
public string CreatedBy { get; set; }
public bool PrintIssue { get; set; }
[MaxLength(250)]
public string PrintAmount { get; set; }
[MaxLength(40)]
public string Beneficiary { get; set; }
[MaxLength(9)]
public string WarrantType { get; set; }
public bool Void { get; set; }
public DateTime? DateRequested { get; set; }
[MaxLength(9)]
public string OrigCheckNum { get; set; }
}
}