所以我得到了一个Blazor编辑页面,需要更新字段。我的主要问题是试图返回对象";对";进行更改并刷新屏幕;
来自blazor页面的呼叫:
<div class="form-group">
<button class="btn btn-primary edit-btn" style="float: right;" @onclick="@SaveChanges">Save Changes</button>
</div>
protected async Task SaveChanges()
{
clientdto = await apiService.SaveDtoAsync(ClientID, clientdto);
this.StateHasChanged();
}
API服务
public async Task<ClientDto> SaveDtoAsync(int ClientID, [FromBody] ClientDto ClientDto)
{
_httpClient.DefaultRequestHeaders.Clear();
var Url = "api/clients/" + Convert.ToInt32(ClientID);
var SerializedClientDto = JsonConvert.SerializeObject(ClientDto);
using (var RequestClientDto = new HttpRequestMessage(HttpMethod.Put, Url))
{
RequestClientDto.Content = new StringContent(SerializedClientDto, System.Text.Encoding.UTF8, "application/json");
RequestClientDto.Headers.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
using (var ResponseClientDto = await _httpClient.SendAsync(RequestClientDto))
{
if (!ResponseClientDto.IsSuccessStatusCode)
{
ResponseClientDto.EnsureSuccessStatusCode();
}
else
{
var Response = await ResponseClientDto.Content.ReadAsStringAsync();
var ResponseDto = JsonConvert.DeserializeObject<ClientDto>(Response);
}
}
}
return ResponseDto;
}
这与Blazor无关,您只是试图在比现有范围更高的范围内使用变量。
但是,在决定更正之前,首先需要决定如果从未填充ResponseDto
,该方法应该返回什么。例如,如果它应该抛出异常,那么您可以将return
移动到定义变量的位置(实际上根本不需要变量(,并在方法末尾抛出异常:
//...
else
{
var Response = await ResponseClientDto.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<ClientDto>(Response);
}
}
}
throw new Exception("Some meaningful error message");
}
或者,如果它应该返回null
或该类型的空实例,您可以这样做:
//...
else
{
var Response = await ResponseClientDto.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<ClientDto>(Response);
}
}
}
return null; // or: return new ClientDto();
}
这实际上取决于你希望方法如何表现,有多种方法可以构建它。你只需要确保:
- 您在变量存在的范围内使用变量
- 方法中所有可能的逻辑代码路径都会产生一个结果。(返回值或引发异常。(
这是一个稍微简化的版本,应该等于上面的调用。
public async Task<ClientDto> SaveDtoAsync(int clientID, [FromBody] ClientDto clientDto)
{
_httpClient.DefaultRequestHeaders.Clear();
var response = await _httpClient.PutAsJsonAsync(url, $"api/clients/{clientID}");
if (!response.IsSuccessStatusCode)
{
//TODO: add error handling
return null; //or default;
}
using (MemoryStream ms = await response.Content.ReadAsStreamAsync())
{
return await JsonSerializer.DeserializeAsync<ClientDto>(ms);
}
}
我使用的Http扩展方法可以使Http调用更加可读和可管理。这里需要注意的另一个技巧是,我不是以字符串的形式读取响应内容,而是使用内存流。有了新的Json解析器,我们可以通过这种方式保护一些分配。这意味着GC压力降低。(解析大型json(超过1000个对象(的小提示存在已知的性能缺陷(。
对于一个需要较少更改的版本@David已经发布了一个出色的answear。
@ZoltBendes非常感谢您的帮助,我成功地让它工作了"部分地";,它跑了,但我得到了一个";StatusCode:204,ReasonPhrase:"没有内容",所以从技术上讲,即使一切似乎都很好,它也不会做出改变。这就是我工作的方式,再一次"部分";
HttpResponseMessage ResponseClientDto = await httpClient.PutAsJsonAsync($"api/clients/{ClientID}", ClientDto);
if (!ResponseClientDto.IsSuccessStatusCode)
{
ResponseClientDto.EnsureSuccessStatusCode();
}
var response = await _httpClient.GetAsync($"api/clients/{ClientID}");
var responseContent = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<ClientDto>(responseContent);