Bad request (400) when using PutAsJsonAsync if Model has navigation properties

huangapple go评论60阅读模式
英文:

Bad request (400) when using PutAsJsonAsync if Model has navigation properties

问题

[HttpPut("{Id}")]
public bool UpdateGame(Guid Id, [FromBody] Game game)
{
Game? oldGame = _unitOfWork.Games.GetById(Id);
if (oldGame != null)
{
oldGame.SeasonId = game.SeasonId;
oldGame.VenueId = game.VenueId;
oldGame.GameTypeId = game.GameTypeId;
oldGame.GameTitle = game.GameTitle;
oldGame.GameDateTime = game.GameDateTime;
oldGame.PublishResults = game.PublishResults;
oldGame.GameDetails = game.GameDetails;
oldGame.Buyin = game.Buyin;
oldGame.Fee = game.Fee;
_unitOfWork.Save();
return true;
}
else
{
return false;
}
}

I have tests against the repo and the controller and the update works fine.

I'm now implementing some CRUD pages using Blazor Server:

async Task OnSubmit()
{
if (Game != null)
{
try
{
var response = await _apiClient.httpClient.PutAsJsonAsync($"/api/Games/{Id}", Game);
bool updated = await response.Content.ReadFromJsonAsync();

        if (updated)
        {
            _navManager.NavigateTo("/settings/games");
        }
    }
    catch (Exception ex)
    {
        AlertIsVisible = true;
        Message = ex.Message;
        MessageType = AlertMessageType.Danger;
    }
}

}

This is failing because of a bad request 400, but this is all the output is telling me. The put method in the controller doesn't hit as my breakpoint doesn't trigger.

Simpler models in my app post just fine using similar code.

The difference here I believe is this Game entity:

public class Game
{
    public Guid Id { get; set; }
    public Guid? SeasonId { get; set; }
    public Guid? GameTypeId { get; set; }
    public Guid? VenueId { get; set; }
    public string? GameTitle { get; set; }
    public DateTime GameDateTime { get; set; }
    public bool PublishResults { get; set; }
    public string? GameDetails { get; set; }
    public double Buyin { get; set; }
    public double Fee { get; set; }

    public virtual Season Season { get; set; } = default!;
    public virtual GameType GameType { get; set; } = default!;
    public virtual Venue Venue { get to know what it actually works while you are having these errors/set; } = default!;
    public virtual ICollection<Result> Results { get; set; } = new HashSet<Result>();
}

I think there is a serialisation issue with the navigation properties (Season, GameType and Venue - not the Results collection). If I remove the navigation properties the update succeeds. I'm at a loss at this point on how to handle the put request so that it works with the navigation properties on my model.

英文:

I am creating a simple API and I have a method that handles the update of a game:

    [HttpPut(&quot;{Id}&quot;)]
    public bool UpdateGame(Guid Id, [FromBody] Game game)
    {
        Game? oldGame = _unitOfWork.Games.GetById(Id);
        if (oldGame != null)
        {
            oldGame.SeasonId = game.SeasonId;
            oldGame.VenueId = game.VenueId;
            oldGame.GameTypeId = game.GameTypeId;
            oldGame.GameTitle = game.GameTitle;
            oldGame.GameDateTime = game.GameDateTime;
            oldGame.PublishResults = game.PublishResults;
            oldGame.GameDetails = game.GameDetails;
            oldGame.Buyin = game.Buyin;
            oldGame.Fee = game.Fee;
            _unitOfWork.Save();
            return true;
        }
        else
        {
            return false;
        }
    }

I have tests against the repo and the controller and the update works fine.

I'm now implementing some CRUD pages using Blazor Server:

    async Task OnSubmit()
    {
        if (Game != null)
        {
            try
            {
                var response = await _apiClient.httpClient.PutAsJsonAsync&lt;Game&gt;($&quot;/api/Games/{Id}&quot;, Game);
                bool updated = await response.Content.ReadFromJsonAsync&lt;bool&gt;();

                if (updated)
                {
                    _navManager.NavigateTo(&quot;/settings/games&quot;);
                }
            }
            catch (Exception ex)
            {
                AlertIsVisible = true;
                Message = ex.Message;
                MessageType = AlertMessageType.Danger;
            }
        }
    }

This is failing because of a bad request 400, but this is all the output is telling me. The put method in the controller doesn't hit as my breakpoint doesn't trigger.

Simpler models in my app post just fine using similar code.

The difference here I believe is this Game entity:

public class Game
{
    public Guid Id { get; set; }
    public Guid? SeasonId { get; set; }
    public Guid? GameTypeId { get; set; }
    public Guid? VenueId { get; set; }
    public string? GameTitle { get; set; }
    public DateTime GameDateTime { get; set; }
    public bool PublishResults { get; set; }
    public string? GameDetails { get; set; }
    public double Buyin { get; set; }
    public double Fee { get; set; }

    public virtual Season Season { get; set; } = default!;
    public virtual GameType GameType { get; set; } = default!;
    public virtual Venue Venue { get; set; } = default!;
    public virtual ICollection&lt;Result&gt; Results { get; set; } = new HashSet&lt;Result&gt;();
}

I think there is a serialisation issue with the navigation properties (Season, GameType and Venue - not the Results collection). If I remove the navigation properties the update succeeds. I'm at a loss at this point on how to handle the put request so that it works with the navigation properties on my model.

答案1

得分: 2

你声明Season、GameType和Venue为非Nullable [没有 ?],然后强制设置为默认值!,而对于任何对象来说,默认值是null。

通常,你在知道对象将在尝试使用之前设置为某个值时才使用default!,但这里并非如此。

英文:

You declare Season, GameType and Venue as not Nullable [no ?], and then forcibly set to default!, which for any object is null.

You normally use default! when you know an object will be set to a value before any attempt is made to use it, which is not the case here.

huangapple
  • 本文由 发表于 2023年2月16日 02:50:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/75464245.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定