使用服务器端Blazor,我想将数据从表单发布到我的控制器,但会不断出现400个错误。我尝试了各种不同的修复方法,但似乎缺少一些显而易见的东西。所有相关代码如下。
MacroModel.cs
public class MacroModel
{
[Required]
public string Gender { get; set; }
[Required]
public int Age { get; set; }
[Required]
public int Weight { get; set; }
[Required]
public int HeightFt { get; set; }
[Required]
public int HeightIn { get; set; }
[Required]
public string ActivityLevel { get; set; }
}
PersonController.cs
[Route("api/[controller]")]
[ApiController]
public class PersonController : ControllerBase
{
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
private IMacroCalcService _MacroService = new MacroCalcService();
//[ResponseType(typeof(MacroModel))]
[HttpPost]
public async Task<IActionResult> FromMacroCalculator([FromBody]MacroModel macros)
{
var m = macros; //ignore this
var totalMacros = await _MacroService.startCalculation();
return Ok(totalMacros);
}
}
MacroCalculator.razor
@page "/macrocalculator"
@using Services
@using FoodAndFitnessTracker.Models
@using Newtonsoft.Json
@using System.Net.Http.Headers
@inject HttpClient Http
@inject IMacroCalcService MacroService
<h1>Macro Calculator</h1>
<EditForm Model="@macroModel" OnValidSubmit="@calculateMacros">
<DataAnnotationsValidator />
<fieldset>
<div class="form-group">
<label for="gender">Gender: </label>
<InputSelect id="gender" @bind-Value="macroModel.Gender">
<option value="">Select Gender</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
</InputSelect>
</div>
</fieldset>
<div class="form-group">
<label for="age">Age </label>
<InputNumber Id="age" Name="age" Class="form-control" @bind-Value="macroModel.Age" />
</div>
<div class="form-group">
<label for="weight">Weight (in lbs): </label>
<InputNumber Id="weight" name="weight" Class="form-control" @bind-Value="macroModel.Weight" />
</div>
<fieldset>
<div class="form-group">
Height <br />
<label for="height-ft">ft</label>
<InputNumber Id="height-ft" Class="form-control" max="1" @bind-Value="macroModel.HeightFt" />
<label for="height-in">in </label>
<InputNumber Id="height-in" Class="form-control" max="2" @bind-Value="macroModel.HeightIn" />
</div>
</fieldset>
<fieldset>
<div class="form-group">
<label for="activity-level">Activity Level: </label>
<InputSelect id="activity-level" @bind-Value="macroModel.ActivityLevel">
<option value="">Select Level</option>
<option value="Sedentary">Sedentary</option>
<option value="Moderately-Active">Moderately Active</option>
<option value="Active">Active</option>
</InputSelect>
</div>
</fieldset>
<button type="submit">Ok</button>
</EditForm>
@code {
private MacroModel macroModel { get; set; } = new MacroModel();
private async Task calculateMacros()
{
//List<MacroModel> mac = new List<MacroModel>();
//var json = JsonConvert.SerializeObject(mac, Formatting.Indented);
//var stringContent = new StringContent(json);
Http.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");
var json = JsonConvert.SerializeObject(macroModel, Formatting.None);
var stringContent = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var resr = Http.PostAsync("api/Person/FromMacroCalculator", stringContent).Result;
await MacroService.startCalculation();
//NavHelper.NavigateTo("/showmacros");
}
}
ConfigureServices
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
services.AddSingleton<WeatherForecastService>();
services.AddSingleton<IMacroCalcService, MacroCalcService>();
//services.AddHttpClient();
//Server Side Blazor doesn't register HttpClient by default
if (!services.Any(x => x.ServiceType == typeof(HttpClient)))
{
// Setup HttpClient for server side in a client side compatible fashion
services.AddScoped<HttpClient>(s =>
{
// Creating the URI helper needs to wait until the JS Runtime is initialized, so defer it.
var uriHelper = s.GetRequiredService<NavigationManager>();
return new HttpClient
{
BaseAddress = new Uri(uriHelper.BaseUri)
};
});
}
}
我尝试使用PostAsJsonAsync,可悲的是。 任何帮助,将不胜感激。
答案 0 :(得分:0)
Inject in .razor
@inject HttpClient http;
@inject NavigationManager navigationManager;
@using Newtonsoft.Json;
and do post call in razor
var serialized = JsonConvert.SerializeObject(yourmodal);
var stringContent = new StringContent(serialized, Encoding.UTF8, "application/json");
var result = await http.PostAsync($"{navigationManager.BaseUri}api/method", stringContent).ConfigureAwait(false);
Setup.cs
services.AddScoped<HttpClient>();
Controller
[HttpPost]
public IActionResult Login([FromBody]Model login)
{
IActionResult response = Ok(new { result = ''});
}
答案 1 :(得分:0)
修复了该问题,感谢Muni的帮助,问题根本不在于使用基本uri作为URL的前缀
private async Task calculateMacros()
{
var json = JsonConvert.SerializeObject(macroModel);
var stringContent = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await Http.PostAsync($"{navigationManager.BaseUri}api/Person/FromMacroCalculator", stringContent);
}
答案 2 :(得分:-1)
您可以像这样使用 PostJsonAsync 并删除控制器中的 [FromBody]:
var response = Http.PostAsJsonAsync("api/Person/FromMacroCalculator", macroModel);