2
votes

I have been trying to deploy my asp.net core hosted blazor webassembly app on Azure App Service, however, I am having trouble getting the api to work. When I try and save a user's data in the database, I get a 400 bad request error. It works fine on localhost. I looked around and found advice that suggested that I use the Log Stream in Azure to get a more detailed error message, and here it is although I'm not sure the details really help.

2020-06-22 22:24:54 MYPROJECT POST /api/Register/Post X-ARR-LOG-ID=ef27263e-dead-417a-b136-89a217a6f931 443 - MYIP Mozilla/5.0+(Windows+NT+10.0;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/83.0.4103.97+Safari/537.36 ARRAffinity=7f74b113b9ae575a087ae1fa07a63858e6e34f27224b7aa1a957b06074e65ffd https://myproject.azurewebsites.net/Register

Here is the relevant application code:

//Register.razor in client project
@code {
    private RegisterModel Model = new RegisterModel();
    private bool ShowErrors;

    private List<string> Errors = new List<string>();
    private async Task HandleValidSubmit()
    {
        ShowErrors = false;
        Errors.Clear();
        if (Model.Password.Length >= 6 && Model.Password == Model.ConfirmPassword)
        {
            await HttpClient.PostAsJsonAsync<RegisterModel>("api/Register/Post", Model);
            NavigationManager.NavigateTo("/");
        }
        else 
        {
            if (Model.Password.Length > 100 || Model.Password.Length < 6)
            {
                Errors.Add("Password must be between 6 and 100 characters in length.");
            }
            if (Model.Password != Model.ConfirmPassword)
            {
                Errors.Add("Passwords do not match.");
            }
            ShowErrors = true;
        }
    }
}

//RegisterController.cs in server project
[Route("api/Register")]
    public class RegisterController : Controller
    {
        private UserContext UserContext { get; set; }
        private IHasher Hasher = new Pbkdf2Hasher();
        public RegisterController (UserContext userContext)
        {
            UserContext = userContext;
        }

        [RequireHttps]
        [HttpPost]
        [Route("Post")]
        public async Task Post([FromBody]RegisterModel model)
        {
            var user = new UserModel
            {
                Email = model.Email,
                Password = Hasher.Hash(model.Password)
            };
            await UserContext.AddAsync(user);
            await UserContext.SaveChangesAsync();
        }
    }

//Startup.cs in Server project
            public void ConfigureServices(IServiceCollection services)
                services.AddDbContext<UserContext>(options =>
                    options.UseSqlServer(Configuration.GetConnectionString("UsersConnection"),
                    sqlServerOptionsAction: sqlOptions =>
                    {
                        sqlOptions.EnableRetryOnFailure();
                    }));

On publishing the project, I configured an Azure SQL Database for 'users', checked the checkboxes to use the UsersConnection string at runtime, and apply the UserContext Entity Framework Migration on publish.

I am using visual studio 2019, and the target framework is netcoreapp3.1. I'd appreciate any guidance. Thanks!

Edit

After looking at the detailed logs, apparently the database isn't even being made?

INSERT INTO [Users] ([Email], [Password])
VALUES (@p0, @p1);
2020-06-22 22:19:47.208 +00:00 [Error] Microsoft.EntityFrameworkCore.Update: An exception occurred in the database while saving changes for context type 'BlazorTodos.Server.Data.UserContext'.
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
 ---> Microsoft.Data.SqlClient.SqlException (0x80131904): Invalid object name 'Users'.
1
According to your description, because you are running normally in local, there is currently a problem deploying to Azure Web App. My suggestions are:Jason Pan
1. Make sure the database connection is normal, there are many ways to test, for example, after opening the home page, insert a piece of data into the temporarily created table in the database.Jason Pan
2. Make sure that each field and attribute of the User table in the database are consistent with the local database. Run it again locally, and try to register the registered user's information both locally and on the deployed website. Pay attention to keeping the registered user's information consistent.Jason Pan
3. After the above two suggestions, the problem is still not resolved. It is recommended to debug the breakpoint and set the published file to Debug mode instead of Publish. For details, please refer to the official documentation.Jason Pan
You can query log in portal about X-ARR-LOG-ID. stackoverflow.com/questions/34858334/azure-http-log-explainedJason Pan

1 Answers

1
votes

Thanks for all the suggestions, Jason. Helped me head in the right direction.

The problem was quite silly. Apparently the Database and Entity Framework settings had automatically come up with the same string for both my "Users" and "Todos" databases:

Data Source=tcp:myserver.database.windows.net,1433;Initial Catalog=todos;User Id=<myid>@myserver;Password=<my-password>

But I hadn't noticed that it was the same string. I just had to change Initial Catalog to users and re check the "use this connection string at runtime" and "apply this migration on publish" boxes again with the edited string. That solved the issue.