Reputation: 193
I've been trying to learn Blazor WebAssembly programming and have been doing a follow-along project along with the Pluralsight course I'm working on.
What happens is that the PutAsync() method in the following code fails:
public async Task UpdateEmployee(Employee employee)
{
try
{
var jsonString = JsonSerializer.Serialize(employee).ToString();
var employeeJson =
new StringContent(JsonSerializer.Serialize(employee), Encoding.UTF8, "application/json");
await _httpClient.PutAsync($"/api/employee", employeeJson);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
This code is located in a service class, and the target method that has the HttpPut attribute either doesn't seem to get called, or the breakpoint I place in it never gets hit.
[HttpPut]
public IActionResult UpdateEmployee([FromBody] Employee employee)
{
if (employee == null)
return BadRequest();
if (employee.FirstName == string.Empty || employee.LastName == string.Empty)
{
ModelState.AddModelError("Name/FirstName", "The name or first name shouldn't be empty");
}
if (!ModelState.IsValid)
return BadRequest(ModelState);
var employeeToUpdate = _employeeRepository.GetEmployeeById(employee.EmployeeId);
if (employeeToUpdate == null)
return NotFound();
_employeeRepository.UpdateEmployee(employee);
return NoContent(); //success
}
I put the breakpoint on the if (employee == null)
line, but it doesn't get hit. I initially had a lot of problems with breakpoints not being hit, but ever since I switched from Firefox to Chrome for my testing, it's been a lot better. Yet, the execution doesn't seem to get here. The routing attributes at the top of this target class looks like the following:
[Route("api/[controller]")]
[ApiController]
The class itself is called EmployeeController
, so I would think that the "api/employee"
attribute should reach it.
I've added a try/catch block around the failing code in the first code block I've posted, and when I step through, I see that there's an exception that gets thrown after I try to step over the PutAsync() method. But when I go to command window to se what the content of ex.Message is, I get the "Unable to Evaluate" error in Visual Studio.
If I step through, I see the execution hitting some bound fields in the Razor file that displays the edit form, but I don't know enough about Razor to really deduce what is going on. There are numerous fields in there that look like this:
<div class="form-group row">
<label for="lastName" class="col-sm-3">Last name: </label>
<InputText id="lastName" @bind-Value="@Employee.LastName" class="form-control col-sm-8" placeholder="Enter last name"></InputText>
</div>
<div class="form-group row">
<label for="firstName" class="col-sm-3">First name: </label>
<InputText id="firstName" class="form-control col-sm-8" @bind-Value="@Employee.FirstName" placeholder="Enter first name"></InputText>
</div>
<div class="form-group row">
<label for="birthdate" class="col-sm-3">Birthdate: </label>
<InputDate id="birthdate" class="form-control col-sm-8" @bind-Value="@Employee.BirthDate" placeholder="Enter birthdate"></InputDate>
</div>
<div class="form-group row">
<label for="email" class="col-sm-3">Email: </label>
<InputText id="email" class="form-control col-sm-8" @bind-Value="@Employee.Email" placeholder="Enter email"></InputText>
</div>
And then, at some point, while stepping through, a lot of the fields get skipped, and the execution seems to leave the Razor file abruptly. I am not sure what to make of this, and since I have been largely absent from .Net for the last several years, it all does feel a bit overwhelming. I am not quite sure how the PutAsync() method call failure really translates into these possible data binding errors, but I am guessing that PutAsync() is just a vehicle to call whatever code has the [HttpPut] attribute, and that any kind of exception anywhere down the line from this method call will cause the PutAsync() call to fail. Would that be accurate or not?
Upvotes: 0
Views: 363
Reputation: 193
Thank you all so much for all the helpful advice, especially the Browser Dev Tools console tip.
So, I changed the System.Diagnostics.Debug.WriteLine(ex.Message)
line to Console(ex.Message)
, and the error I saw in the Browser Dev Tools console was:
Access to fetch at 'https://localhost:44340/api/employee' from origin 'https://localhost:44362' has been blocked by CORS policy: Method PUT is not allowed by Access-Control-Allow-Methods in preflight response.
I went to the ConfigureServices()
method in the startup.cs file of the web service, and I changed the code from
services.AddCors(options =>
{
options.AddPolicy("Open", builder => builder.AllowAnyOrigin().AllowAnyHeader());
});
to
services.AddCors(options =>
{
options.AddPolicy("Open", builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
});
The error is gone, and the employee record gets saved correctly now. I do realize that this isn't exactly a sound programming practice to call something like AllowAnyMethod()
, but for the purposes of this course, it's sufficient for now. Thank you all again!
Upvotes: 1
Reputation: 2032
EditForm
and model
or EditContext
.DataAnnotationsValidator
and/or ValidationSummary
component to validate your form before submitting.OnValidSubmit
method to submit your form only when has a validate controls.OnValidSubmit
, check if your EditContext
validate before request PutAsync()
.Upvotes: 1
Reputation: 303
try to await "api/employee"
var employeeToUpdate = await _employeeRepository.GetEmployeeById(employee.EmployeeId);
Upvotes: 1