[英]Angular 4 Http Post not hitting API Post Method in DotNet Core 2.0 API Controller
[英]Angular 6 HttpClient Post not hitting API Post Method in DotNet Core 2.2 API Controller
我已经从 MVC/AngularJS 1.x 升级到 DotNet Core 2.2/Angular 6.x。 使用@angular/common/http
大多数情况下,它是轻而易举的,但 Web API 正在扼杀我。 我在几分钟内就可以开始工作,但我花了一周的时间在阳光下尝试一切以使 Web Post 正常工作。
我在这里所做的很容易复制。
进入 Visual Studio 17 并单击文件/新建项目
选择已安装/Visual C#/.NET Core
选择模板:ASP.NET core Web Application
在辅助屏幕上将顶部的下拉列表设置为 .NET Core 和 ASP.NET Core 2.2
选择红盾“A”角模板
让项目拉下依赖并重建。
一切都是微软提供的开箱即用演示应用程序,除了:
将按钮添加到屏幕上。
将代码添加到 .ts 以调用 API Controller
将输入参数添加到控制器中的 get 方法
给控制器添加一个非常简单的post方法
我也在尝试获得 DotNet Core 2.0/Angular 4.x。 使用@angular/http 处理完全相同的结果。 获取非常简单,但我已经尝试了各种配置以使帖子正常工作。 我也会为其他版本发布这样的帖子。 现在,我只是想尽我所能,把 AngularJS 1.x 抛在脑后。
import { Component, Inject } from '@angular/core'; import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http'; @Component({ selector: 'app-fetch-data', templateUrl: './fetch-data.component.html' }) export class FetchDataComponent { public Http: HttpClient; public BaseURL: string; public HttpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; public startDateIndex = 0; public forecasts: WeatherForecast[] = []; public forecast: WeatherForecast = { dateFormatted: "3/27/2020", temperatureC: 0, temperatureF: 32, summary: "Cold Post" }; constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string) { this.Http = http; this.BaseURL = baseUrl; http.get<WeatherForecast[]>(baseUrl + 'api/SampleData/WeatherForecasts') .subscribe(result => { this.forecasts = result; }, error => console.error(error)); } public OnClick(pControl: string) { //console.log("LogOn.OnClick * pControl=" + pControl); switch (pControl) { case "Prior": this.startDateIndex -= 5; this.Http.get<WeatherForecast[]>(this.BaseURL + 'api/SampleData/WeatherForecasts/', { params: new HttpParams().set('startDateIndex', this.startDateIndex.toString()) }) .subscribe(result => { this.forecasts = result; }, error => console.error(error)); break; case "Next": this.startDateIndex += 5; this.Http.get<WeatherForecast[]>(this.BaseURL + 'api/SampleData/WeatherForecasts/', { params: new HttpParams().set('startDateIndex', this.startDateIndex.toString()) }) .subscribe(result => { this.forecasts = result; }, error => console.error(error)); break; case "Post": console.log("Post * this.forecast=" + JSON.stringify(this.forecast) + "this.HttpOptions=" + JSON.stringify(this.HttpOptions)); this.Http.post<WeatherForecast>(this.BaseURL + '/api/SampleData/PostWeatherForecast/', this.forecast, this.HttpOptions); } } } interface WeatherForecast { dateFormatted: string; temperatureC: number; temperatureF: number; summary: string; }
<h1>Weather forecast</h1> <p>This component demonstrates fetching data from the server.</p> <p *ngIf="!forecasts"><em>Loading...</em></p> <table class='table table-striped' *ngIf="forecasts"> <thead> <tr> <th>Date</th> <th>Temp. (C)</th> <th>Temp. (F)</th> <th>Summary</th> </tr> </thead> <tbody> <tr *ngFor="let forecast of forecasts"> <td>{{ forecast.dateFormatted }}</td> <td>{{ forecast.temperatureC }}</td> <td>{{ forecast.temperatureF }}</td> <td>{{ forecast.summary }}</td> </tr> </tbody> </table> <button class='btn btn-default pull-left' (click)="OnClick('Prior')">Previous</button> <button class='btn btn-default pull-left' (click)="OnClick('Next')">Next</button> <button class='btn btn-default pull-right' (click)="OnClick('Post')">Post</button>
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
namespace NG_22.Controllers
{
[Route("api/[controller]")]
public class SampleDataController : Controller
{
private static string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
[HttpGet("[action]")]
public IEnumerable<WeatherForecast> WeatherForecasts(int startDateIndex = 0)
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
DateFormatted = DateTime.Now.AddDays(index + startDateIndex).ToString("d"),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
});
}
[HttpPost("[action]")]
public WeatherForecast PostWeatherForecast([FromBody] WeatherForecast weatherForecast)
{
var forecast = weatherForecast;
//return weatherForecast;
return new WeatherForecast()
{
DateFormatted = DateTime.Now.ToString("d"),
TemperatureC = 30,
Summary = Summaries[2]
};
}
public class WeatherForecast
{
public string DateFormatted { get; set; }
public int TemperatureC { get; set; }
public string Summary { get; set; }
public int TemperatureF
{
get
{
return 32 + (int)(TemperatureC / 0.5556);
}
}
}
}
}
解决了!!!!
问题是没有任何订阅。 如果没有人在听,它也不会打扰给邮政打电话。 我添加了一个 .subscribe 并且效果很好。
import { Component, Inject } from '@angular/core';
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
@Component({
selector: 'app-fetch-data',
templateUrl: './fetch-data.component.html'
})
export class FetchDataComponent {
public Http: HttpClient;
public BaseURL: string;
public HttpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
public startDateIndex = 0;
public forecasts: WeatherForecast[] = [];
public forecast: WeatherForecast = {
dateFormatted: "3/27/2020",
temperatureC: 0,
temperatureF: 32,
summary: "Cold Post"
};
constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
this.Http = http;
this.BaseURL = baseUrl;
http.get<WeatherForecast[]>(baseUrl + 'api/SampleData/WeatherForecasts')
.subscribe(result => { this.forecasts = result; }, error => console.error(error));
}
public OnClick(pControl: string) {
//console.log("LogOn.OnClick * pControl=" + pControl);
switch (pControl) {
case "Prior":
this.startDateIndex -= 5;
this.Http.get<WeatherForecast[]>(this.BaseURL + 'api/SampleData/WeatherForecasts/', { params: new HttpParams().set('startDateIndex', this.startDateIndex.toString()) })
.subscribe(result => { this.forecasts = result; }, error => console.error(error));
break;
case "Next":
this.startDateIndex += 5;
this.Http.get<WeatherForecast[]>(this.BaseURL + 'api/SampleData/WeatherForecasts/', { params: new HttpParams().set('startDateIndex', this.startDateIndex.toString()) })
.subscribe(result => { this.forecasts = result; }, error => console.error(error));
break;
case "Post":
console.log("Post * this.forecast=" + JSON.stringify(this.forecast) + "this.HttpOptions=" + JSON.stringify(this.HttpOptions));
this.Http.post<WeatherForecast>(this.BaseURL + '/api/SampleData/PostWeatherForecast/', this.forecast, this.HttpOptions)
.subscribe(result => { console.log("Posted" + JSON.stringify(result)); }, error => console.error(error));
}
}
}
interface WeatherForecast {
dateFormatted: string;
temperatureC: number;
temperatureF: number;
summary: string;
}
改进的答案。 不需要接口和其他较小的改进和删除不必要的代码。
import { Component, Inject } from '@angular/core'; import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http'; @Component({ selector: 'app-fetch-data', templateUrl: './fetch-data.component.html' }) export class FetchDataComponent { public Http: HttpClient; public BaseURL: string; public HttpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; public startDateIndex = 0; public forecasts: any; public forecast = { dateFormatted: "3/27/2020", temperatureC: 0, temperatureF: 32, summary: "Cold Post", Data: { color: "red", Size: "Large" } }; constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string) { this.Http = http; this.BaseURL = baseUrl; http.get(baseUrl + 'api/SampleData/WeatherForecasts') .subscribe(result => { this.forecasts = result; }, error => console.error(error)); } public OnClick(pControl: string) { //console.log("LogOn.OnClick * pControl=" + pControl); switch (pControl) { case "Prior": this.startDateIndex -= 5; this.Http.get(this.BaseURL + 'api/SampleData/WeatherForecasts/', { params: new HttpParams().set('startDateIndex', this.startDateIndex.toString()) }) .subscribe(result => { this.forecasts = result; }, error => console.error(error)); break; case "Next": this.startDateIndex += 5; this.Http.get(this.BaseURL + 'api/SampleData/WeatherForecasts/', { params: new HttpParams().set('startDateIndex', this.startDateIndex.toString()) }) .subscribe(result => { this.forecasts = result; }, error => console.error(error)); break; case "Post": console.log("Post * this.forecast=" + JSON.stringify(this.forecast) + "this.HttpOptions=" + JSON.stringify(this.HttpOptions)); this.Http.post(this.BaseURL + '/api/SampleData/PostWeatherForecast/', this.forecast, this.HttpOptions) .subscribe(result => { alert("Posted" + JSON.stringify(result)); }, error => console.error(error)); } } }
<h1>Weather forecast</h1> <p>This component demonstrates fetching data from the server.</p> <p *ngIf="!forecasts"><em>Loading...</em></p> <table class='table table-striped' *ngIf="forecasts"> <thead> <tr> <th>Date</th> <th>Temp. (C)</th> <th>Temp. (F)</th> <th>Summary</th> </tr> </thead> <tbody> <tr *ngFor="let forecast of forecasts"> <td>{{ forecast.dateFormatted }}</td> <td>{{ forecast.temperatureC }}</td> <td>{{ forecast.temperatureF }}</td> <td>{{ forecast.summary }}</td> </tr> </tbody> </table> <button class='btn btn-default pull-left' (click)="OnClick('Prior')">Previous</button> <button class='btn btn-default pull-left' (click)="OnClick('Next')">Next</button> <button class='btn btn-default pull-right' (click)="OnClick('Post')">Post</button>
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
namespace NG_22.Controllers
{
[Route("api/[controller]/[action]")]
public class SampleDataController : Controller
{
private static string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
[HttpGet]
public IEnumerable<WeatherForecast> WeatherForecasts(int startDateIndex = 0)
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
DateFormatted = DateTime.Now.AddDays(index + startDateIndex).ToString("d"),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
});
}
[HttpPost]
public object PostWeatherForecast([FromBody] WeatherForecast weatherForecast)
{
var forecast = weatherForecast;
//return weatherForecast;
return new
{
DateFormatted = DateTime.Now.ToString("d"),
TemperatureC = 30,
Summary = Summaries[2]
};
}
public class WeatherForecast
{
public string DateFormatted { get; set; }
public int TemperatureC { get; set; }
public string Summary { get; set; }
public int TemperatureF
{
get
{
return 32 + (int)(TemperatureC / 0.5556);
}
}
public object Data { get; set; }
}
}
}
using DMChess_Data.Model;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace DMChess_Data
{
public class Entities
{
private dmchessContext DMCConnection = new dmchessContext();
private Guid AppId = new Guid("B6C093C8-AE8C-40CD-9E0D-3BD2118422EC");
public bool SaveChanges()
{
try
{
DMCConnection.SaveChangesAsync();
}
catch(Exception pException)
//catch (Microsoft.EntityFrameworkCore.)
//catch (System.Data.Entity.Validation.DbEntityValidationException ex)
{
var ex = pException;
//foreach (var eve in ex.EntityValidationErrors)
//{
// var type = eve.Entry.Entity.GetType().Name;
// var state = eve.Entry.State;
// foreach (var ve in eve.ValidationErrors)
// {
// var propertyName = ve.PropertyName;
// var ErrorMessage = ve.ErrorMessage;
// }
//}
//var m = ex;
throw;
}
DMCConnection.SaveChanges();
return true;
}
#region AUsers
public AUsers AUsersGet(Guid pId, string pPassword)
{
return DMCConnection.AUsers.FirstOrDefault(x => x.KAppId == AppId && x.KId == pId && x.Password == pPassword);
}
public AUsers AUsersGet(string pEmailAddress, string pPassword)
{
return DMCConnection.AUsers.FirstOrDefault(x => x.KAppId == AppId && x.EmailAddress == pEmailAddress);
}
#endregion
#region DProfiles
public DProfiles DProfileGet(Guid pKUserId, int pKIdx)
{
return DMCConnection.DProfiles.FirstOrDefault(x => x.KAppId == AppId && x.KUserId == pKUserId && x.KIdx == pKIdx);
}
public List<DProfiles> DProfilesGet(string pUserIdName)
{
return DMCConnection.DProfiles.Where(x => x.KAppId == AppId && x.UserIdToLower == pUserIdName.ToLower()).ToList();
}
#endregion
}
}
using D2Chess.Server.IO;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
namespace D2Chess.Controllers
{
[Route("api/[controller]/[action]")]
public class WebController : Controller
{
#region Init
private JsonSerializer jsonSerializer = new JsonSerializer();
private Repository repository = new Repository();
public WebController(IHubContext<D2Chess.Server.IO.Hub> hubContext) { D2Chess.Server.IO.Hub.StaticContext = hubContext; }
#endregion
#region Classes
public class Parms {
public Guid? TokenId { get; set; }
public string Action { get; set; }
public object Data { get; set; }
}
public class Result
{
public bool Success { get; set; }
public object Data { get; set; }
public Result(bool pSuccess, object pData = null) { this.Success = pSuccess; this.Data = pData; }
}
#endregion
#region Sync Methods
[HttpGet]
public object Get(string pAction, string pKey = "", Guid? pTokenId = null)
{
return repository.WebGet(pAction, pKey, pTokenId);
//var result = repository.WebGet(pAction, pKey, pTokenId);
//return result;
}
[HttpPost]
public object Post([FromBody] object pParms)
{
var parms = ((JObject)pParms).ToObject<Parms>();
return repository.WebPost(parms.Action, parms.Data, parms.TokenId);
//var result = repository.WebPost(parms.Action, parms.Data, parms.TokenId);
//return result;
}
#endregion
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.