[英]Can't update nor create data using Entity Framework Core 2.0
Edit: Got past the issue in the PUT (was a null value going into a non-null field), but still having issues with the POST 编辑:在PUT中解决了问题(将null值输入到非null字段中),但POST仍然存在问题
I'm trying to setup a simple generic repository in my project using EF Core 2. The Gets and the Updates work fine but I'm having issues with the Create. 我正在尝试使用EF Core 2在我的项目中设置一个简单的通用存储库。“获取”和“更新”工作正常,但是“创建”存在问题。 Specifically, the value received at HttpPost in the controller is null. 具体来说,在控制器的HttpPost处接收到的值为null。 What is weird is that the HttpPut works fine in the controller and the Company is received with all its data. 奇怪的是HttpPut在控制器中工作正常,并且公司收到了所有数据。
Here is my generic repo class: 这是我的通用仓库类:
public class GenericRepository<TEntity> : IGenericRepository<TEntity>
where TEntity : class, IEntity
{
protected DriverDbContext _dbContext;
protected DbSet<TEntity> _dbSet;
public GenericRepository(DriverDbContext dbContext)
{
_dbContext = dbContext;
_dbSet = dbContext.Set<TEntity>();
}
public async Task<IEnumerable<TEntity>> GetAll()
{
return await _dbSet.AsNoTracking().ToListAsync();
}
public async Task<TEntity> GetById(long id)
{
return await _dbSet
.AsNoTracking()
.FirstOrDefaultAsync(e => e.Id == id);
}
public async Task Create(TEntity entity)
{
_dbSet.Add(entity);
await _dbContext.SaveChangesAsync();
}
public async Task Update(TEntity entity)
{
// entity has good data but SavaChangesAsync does nothing
_dbSet.Update(entity);
await _dbContext.SaveChangesAsync();
}
public async Task Delete(long id)
{
var entity = await _dbSet.FindAsync(id);
_dbSet.Remove(entity);
await _dbContext.SaveChangesAsync();
}
}
Here is my controller: 这是我的控制器:
[Produces("application/json")]
[Route("api/Company")]
public class CompanyController : Controller
{
private ICompanyRepository _repository;
public CompanyController(ICompanyRepository repository)
{
_repository = repository;
}
[HttpGet]
public async Task<IActionResult> GetCompanies()
{
return Json(await _repository.GetAll());
}
[HttpGet("{id}")]
public async Task<IActionResult> GetCompany(int id)
{
var company = await _repository.GetById(id);
if (company == null)
{
return NotFound();
}
return Json(company);
}
[HttpPost()]
public async Task<IActionResult> CreateCompany([FromBody]CompanyViewModel company)
{
if (company == null)
{
return BadRequest();
}
var newCompany = Mapper.Map<Company>(company);
await _repository.Create(newCompany);
return Created($"/api/company/{company.Name}", Mapper.Map<CompanyViewModel>(newCompany));
}
[HttpPut()]
public async Task<IActionResult> UpdateCompany([FromBody]CompanyViewModel company)
{
if (company==null)
{
return BadRequest();
}
if (_repository.GetById(company.Id) == null)
{
return NotFound();
}
var updatedCompany = Mapper.Map<Company>(company);
await _repository.Update(updatedCompany);
return new NoContentResult();
}
}
Here is the company entity: 这是公司实体:
public class Company : IEntity
{
public long Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string Comments { get; set; }
public string Type { get; set; }
public bool Blacklisted { get; set; }
public string BlacklistedComments { get; set; }
public string BrokerAgreementStatus { get; set; }
public float CompanyInvoiceDiscount { get; set; }
public float PassThroughFee { get; set; }
public int StandardHoursBilled { get; set; }
public float StandardGM { get; set; }
public float StandardMarkupFromBase { get; set; }
public float StandardMarkupFromLoaded { get; set; }
public float StandardEquipmentCost { get; set; }
public long LastEditByUserID { get; set; }
public DateTime? LastEditDate { get; set; }
}
Here is the company view model: 这是公司视图模型:
public class CompanyViewModel
{
public long Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string Comments { get; set; }
public string Type { get; set; }
public bool Blacklisted { get; set; }
public string BlacklistedComments { get; set; }
public string BrokerAgreementStatus { get; set; }
public float CompanyInvoiceDiscount { get; set; }
public float PassThroughFee { get; set; }
public int StandardHoursBilled { get; set; }
public float StandardGM { get; set; }
public float StandardMarkupFromBase { get; set; }
public float StandardMarkupFromLoaded { get; set; }
public float StandardEquipmentCost { get; set; }
public long LastEditByUserId { get; set; }
public DateTime LastEditDate { get; set; }
}
Here is my angular company service: 这是我的有角公司服务:
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Rx';
import { of } from 'rxjs/observable/of';
import { catchError, map, tap } from 'rxjs/operators';
import { Company } from './company';
import { MessageService } from '../message/message.service';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
@Injectable()
export class CompanyService {
private baseUrl = 'api/company';
constructor(
private http: HttpClient,
private messageService: MessageService) {
}
private log(message: string) {
this.messageService.add('CompanyService: ' + message);
}
getCompanies(): Observable<Company[]> {
return this.http.get<Company[]>(this.baseUrl)
.pipe(
tap(companies => this.log(`fetched companies`)),
catchError(this.handleError('getCompanies', []))
);
}
//Handle Http operation that failed.
//Let the app continue.
//@param operation - name of the operation that failed
//@param result - optional value to return as the observable result
getCompany(id: number): Observable<Company> {
if (id === 0) {
return Observable.of(this.initializeCompany());
}
return this.http.get<Company>(`${this.baseUrl}/${id}`).pipe(
tap(_ => this.log(`fetched Company id=${id}`)),
catchError(this.handleError<Company>(`getCompany id=${id}`))
);
}
initializeCompany(): Company {
return {
id: 0,
name: null,
address: null,
city: null,
state: null,
};
}
saveCompany(company: Company): Observable<Company> {
if (company.id === null) {
return this.addCompany(company);
}
return this.updateCompany(company);
}
updateCompany(company: Company): Observable<Company> {
return this.http.put<Company>(this.baseUrl, company, httpOptions).pipe(
tap((company: Company) => this.log(`updated company id=${company.id}`)),
catchError(this.handleError<any>('updateCompany'))
);
}
addCompany(company: Company): Observable<Company> {
return this.http.post<Company>(this.baseUrl, company, httpOptions).pipe(
tap((company: Company) => this.log(`added company id=${company.id}`)),
catchError(this.handleError<any>('addCompany'))
);
}
private handleError<T>(operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
// TODO: send the error to remote logging infrastructure
console.error(error); // log to console instead
// TODO: better job of transforming error for user consumption
//this.log(`${operation} failed: ${error.message}`);
// Let the app keep running by returning an empty result.
return of(result as T);
};
}
}
Here is the startup.cs 这是startup.cs
public class Startup
{
private IConfiguration _config;
public Startup(IConfiguration config)
{
_config = config;
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DriverDbContext>(options => options.UseSqlServer(_config.GetConnectionString("DriverDBConnection")));
services.AddMvc();
services.AddScoped<ICompanyRepository, CompanyRespository>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true
});
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
Mapper.Initialize(config =>
{
config.CreateMap<CompanyViewModel, Company>().ReverseMap();
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
}
}
The CompanyRespository is an empty child class of the GenericRepository CompanyRespository是GenericRepository的空子类
Here is the request payload to the Post: 这是到Post的请求有效负载:
{"id":null,
"name":"Some Company",
"address":null,
"city":null,
"state":"",
"zipcode":null,
"phone":null,
"email":null,
"comments":null,
"type":null,
"blacklisted":false,
"blacklistedComments":null,
"brokerAgreementStatus":"N/A",
"companyInvoiceDiscount":0,
"passThroughFee":0,
"standardHoursBilled":0,
"standardGM":0,
"standardMarkupFromBase":0,
"standardMarkupFromLoaded":0,
"standardEquipmentCost":0,
"lastEditByUserID":0,
"lastEditDate":"2018-01-10T23:03:05.303Z"}
Here is the Request Header 这是请求标题
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.9
Connection:keep-alive
Content-Length:447
Content-Type:application/json
Host:localhost:56241
Origin:http://localhost:56241
Referer:http://localhost:56241/companies/0/edit
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
public async Task Create(TEntity entity)
{
_dbSet.Add(entity);
await _dbContext.SaveChangesAsync();
}
public async Task Update(TEntity entity)
{
// entity has good data but SavaChangesAsync does nothing
_dbSet.Update(entity);
_dbContext.Entry(entity).State = EntityState.Modified;
await _dbContext.SaveChangesAsync();
}
public async Task Delete(long id)
{
var entity = await _dbSet.FindAsync(id);
if (_dbContext.Entry(entity).State = EntityState.Detached)
_dbSet.Attach(entity);
_dbSet.Remove(entity);
await _dbContext.SaveChangesAsync();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.