인프런 커뮤니티 질문&답변

Young님의 프로필 이미지
Young

작성한 질문수

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part6: 웹 서버

An unhandled exception has occured. See browser dev tools for detail.

작성

·

191

0

blazor ranking app #3을 하던 도중에 스크린샷과 같은 에러가 나타났습니다.스크린샷 2024-02-06 003146.png

콘솔창에는 아래와 같은 에러 메세지가 떠서 제 입력이 userId가 null인 것으로 입력된 것 같습니다.

문제가 있을 수 있어 하단에 제가 작성한 ranking.razor와 RankingService.cs의 코드를 첨부하지만 강의의 내용에서 작성한 코드와 동일하게 작성하였습니다.

ranking.razor

@page "/ranking"
@using RankingApp.Data.Models
@using RankingApp.Data.Services

@inject RankingService RankingService
<h3>Ranking</h3>
@*LoginDisplay.razor의 내용 참조*@
<AuthorizeView>
    <Authorized> @*로그인한 경우*@
        @if (_gameResults == null)
        {
            <p><em>Loading...</em></p>
        }
        else
        {
            <table class="table">
                <thead>
                    <tr>
                        <th>User</th>
                        <th>Score</th>
                        <th>Date</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var gameResult in _gameResults)
                    {
                        <tr>
                            <td>@gameResult.UserName</td>
                            <td>@gameResult.Score</td>
                            <td>@gameResult.Date.ToString()</td>
                        </tr>
                    }
                </tbody>
            </table>

            @*데이터 추가하기*@
            <p>
                <button class="btn btn-primary" @onclick="AddGameResult">
                    Add
                </button>
            </p>

            @if (_showPopup)
            {
                <div class="modal" style="display:block" role="dialog">
                    <div class="modal-dialog">
                        <div class="modal-content">
                            <div class="modal-Header">
                                <h3 class="modal-title">Add/Update GameResult</h3>
                                <button type="button" class="close" @onclick="ClosePopup">
                                    <span area-hidden="true">X</span>
                                </button>
                            </div>
                            <div class="modal-body">
                                <label for="UserName">UserName</label>
                                <input class="form-control" type="text" placeholder="UserName" @bind-value="_gameResult.UserName">
                                <label for="Score">Score</label>
                                <input class="form-control" type="text" placeholder="Score" @bind-value="_gameResult.Score">
                                <button class="btn btn-primary" @onclick="SaveGameResult">
                                    Save
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
            }
        }
    </Authorized>
    <NotAuthorized>
        <p>You are not Authorized</p>
    </NotAuthorized>
</AuthorizeView>


@code {
    List<GameResult> _gameResults;

    bool _showPopup;
    GameResult _gameResult;

    protected override async Task OnInitializedAsync()
    {
        _gameResults = await RankingService.GetGameResultsAsync();
    }

    void AddGameResult()
    {
        @*팝업 띄워주기*@
        _showPopup = true;
        _gameResult = new GameResult() { Id = 0 };

    }

    void ClosePopup()
    {
        _showPopup = false;
    }

    async Task SaveGameResult()
    {
        if(_gameResult.Id==0) //새로 데이터를 추가하는 작업, 이때는 id가 없지만 db에 넣어지면id 자동 생성
        {
            _gameResult.Date=DateTime.Now;
            var result = RankingService.AddGameResult(_gameResult); @*AddGameResult는 rankingService.cs에 있다*@
        }
        else
        {
            //TODO
        }
        _gameResults = await RankingService.GetGameResultsAsync(); @*다시 바뀐 데이터 다시 가져오기*@
    }
}

 

 

RankingService.cs

using RankingApp.Data.Models;

namespace RankingApp.Data.Services
{
    public class RankingService
    {
        ApplicationDbContext _context;
        public RankingService(ApplicationDbContext context)
        {
            _context = context;
        }

        //Create
        public Task<GameResult> AddGameResult(GameResult gameResult)
        {
            _context.GameResults.Add(gameResult);
            _context.SaveChanges(); //db에도 저장

            return Task.FromResult(gameResult);
        }
        //Read
        public Task<List<GameResult>> GetGameResultsAsync()
        {
            List<GameResult> results = _context.GameResults
                .OrderByDescending(item => item.Score)
                .ToList();

            return Task.FromResult(results);
        }

        //Update
        //Delete
    }
}

 

답변 2

0

You should check the error message that appears in the console window to pinpoint the issue where userId is null. This error usually occurs when the Slitherio user is not logged in. Check your ranking.razor file to make sure that it is only accessible when the user is logged in. You are using the AuthorizeView tag, but you may need to perform additional authentication checks.

0

안녕하세요, 인프런 AI 인턴입니다.

Young님, 에러 메시지를 통해 확인해보니 Blazor 애플리케이션에서 ‘UserId’ 컬럼에 NULL 값을 삽입하려다 발생하는 DbUpdateException이네요. ‘UserId’는 NULL을 허용하지 않는 필드임에도 불구하고 현재 로직에서는 값을 제대로 전달하고 있지 않습니다.

제공해주신 RankingService.cs 코드를 확인해보면, GameResult 객체를 추가할 때 UserId에 대한 언급이 없습니다. AddGameResult 함수에서는 GameResult 객체의 Id 속성만을 설정하고 있으며, 이는 Entity Framework에서 GameResults 테이블의 기본 키일 것입니다.

문제 해결을 위해서는 GameResult 객체의 UserId 필드가 현재 로그인한 사용자의 식별자로 설정되게 해야 합니다. 이 정보는 보통 로그인 세션에서 얻을 수 있습니다. 사용자 로그인 상태와 관련된 정보를 관리하고, 데이터베이스에 기록을 저장할 때 이를 활용해 UserId를 설정해주셔야 할 것 같습니다.

이를 위해 다음과 같은 방법을 사용할 수 있습니다:

  1. 현재 로그인한 사용자의 Id를 얻는 코드를 추가하세요.
  2. AddGameResult 함수 내에서 새로운 GameResult 객체를 생성할 때 UserId 필드에 사용자 Id를 설정하세요.

예시로, 사용자의 Id를 가져오는 코드를 RankingService에 추가하거나 SaveGameResult 메소드에서 처리할 수 있습니다. 로그인 세션 및 UserManager 같은 클래스를 활용해 현재 사용자의 정보를 얻는 방법을 검토해보시길 바랍니다.

저의 조언이 문제 해결에 도움이 되길 바랍니다. 추가적인 질문이 있으면 언제든지 문의해주시기 바랍니다.

Young님의 프로필 이미지
Young

작성한 질문수

질문하기