服务器端Blazor-向控制器发布表单数据获取400个请求

时间:2019-10-24 17:11:35

标签: c# asp.net asp.net-core blazor

使用服务器端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,可悲的是。 任何帮助,将不胜感激。

3 个答案:

答案 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);