由于某种原因,我在路由器上导航后,HttpClient请求开始接收400(错误请求)。在导航之前,HttpClient可以使用完全相同的http调用方法完美地工作。这是导航:
let navigationExtras: NavigationExtras = {
queryParams: {
"certificate": JSON.stringify(this.selection.selected[0])
}
};
this.router.navigate(["create"], navigationExtras);
我知道这不是ASP.NET Core控制器中的CORS问题,因为在导航之前不会发生错误请求,并且我确实允许在服务器端使用CORS。
HistoryComponent和CreateCertComponent的代码:
@Component({
selector: 'app-history',
templateUrl: './history.component.html',
styleUrls: ['./history.component.css']
})
export class HistoryComponent implements OnInit {
certificates: CertificateModel[] = [];
dataSource : MatTableDataSource<CertificateModel> = new MatTableDataSource(this.certificates);
displayedColumns: string[] = ['name',
'customer',
'customerOrderNo',
'certificateNo',
'orderACKNNo',
'date',
'select'];
@ViewChild(MatSort) sort: MatSort
@ViewChild("paginator") paginator: MatPaginator;
searchTextfield: string;
searchOptions: string[] = ["Name", "Customer", "Cust. Ord. No.", "Order ACKN No.", "Date"];
selectedSearchOption: string = "Name";
selection = new SelectionModel<CertificateModel>(true, []);
isLoading: boolean;
constructor(private certHttpService: CertificateHttpService,
public errorDialog: MatDialog,
private router: Router
) { }
ngOnInit() {
this.configureDataSource();
this.loadCertificates();
}
loadCertificates() {
this.isLoading = true;
this.certHttpService.getAllPro().then((res => {
this.certificates = res;
this.dataSource.data = this.certificates;
this.isLoading = false;
}).bind(this))
.catch((error => {
this.isLoading = false;
this.openErrorDialog("Error", error.name + ": " + error.message);
}).bind(this));
}
openErrorDialog(title: string, text: string) {
var data = {
"title": title,
"text": text
};
const dialogRef = this.errorDialog.open(ErrorDialogComponent, {
width: '30vw',
height: 'auto',
disableClose: true,
data: data
});
dialogRef.afterClosed().subscribe(result => {
console.log('The dialog was closed');
});
}
editClicked() {
let navigationExtras: NavigationExtras = {
queryParams: {
"certificate": JSON.stringify(this.selection.selected[0])
}
};
this.router.navigate(["create"], navigationExtras);
}
deleteClicked() {
this.certHttpService.deletePro(this.selection.selected).then((res => {
this.selection.selected.forEach(e0 => {
var index = this.certificates.findIndex(e1 => {
return e0.guid == e1.guid;
});
this.certificates.splice(index, 1);
});
this.dataSource = new MatTableDataSource<CertificateModel>(this.certificates);
this.configureDataSource();
this.selection = new SelectionModel<CertificateModel>(true, []);
}).bind(this));
}
searchFieldOnChange() {
console.log("searchfield on change!");
}
applyFilter(filterValue: string) {
filterValue = filterValue.toLowerCase();
this.dataSource.filter = filterValue;
}
isAllSelected() : boolean {
const numSelected = this.selection.selected.length;
const numRows = this.dataSource.data.length;
return numSelected == numRows;
}
masterToggle() {
this.isAllSelected() ?
this.selection.clear() :
this.dataSource.data.forEach(row => this.selection.select(row));
}
configureDataSource () {
this.dataSource.sortingDataAccessor = (data: any, sortHeaderId: string): string => {
if (typeof data[sortHeaderId] === 'string')
return data[sortHeaderId].toLocaleLowerCase();
return data[sortHeaderId];
};
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator;
this.dataSource.filterPredicate =
((data: CertificateModel, filter: string) => {
if(this.selectedSearchOption == this.searchOptions[0] && data.name != null)
return data.name.toLowerCase().indexOf(filter) != -1;
else if(this.selectedSearchOption == this.searchOptions[1] && data.customer != null)
return data.customer.toLowerCase().indexOf(filter) != -1;
else if(this.selectedSearchOption == this.searchOptions[2] && data.customerOrderNo != null)
return data.customerOrderNo.toLowerCase().indexOf(filter) != -1;
else if(this.selectedSearchOption == this.searchOptions[3] && data.customerArtNo != null)
return data.customerArtNo.toLowerCase().indexOf(filter) != -1;
else if(this.selectedSearchOption == this.searchOptions[4] && data.date != null)
return data.date.toLowerCase().indexOf(filter) != -1;
});
}
refreshClicked() {
this.loadCertificates();
}
}
@Component({
selector: 'app-create-cert',
templateUrl: './create-cert.component.html',
styleUrls: ['./create-cert.component.css'],
encapsulation: ViewEncapsulation.None
})
export class CreateCertComponent implements OnInit {
resultRowWrappers: ResultRowWrapper[];
customerTextfield: string;
customerOrderNoTextfield: string;
customerArtNoTextfield: string;
specificationTextfield: string;
certificateNoTextfield: string;
dateTextfield: string;
deliveredQuantityTextfield: string;
orderACKNNoTextfield: string;
batchNumberTextfield: string;
propertyTextfield: string;
unitTextfield: string;
testResultTextfield: string;
signaturTextfield: string;
newCertName: string;
editedCertificate: CertificateModel
isEditing: boolean;
disableDeleteButton: boolean;
titleRow0Textfield: string;
titleRow1Textfield: string;
titleRow2Textfield: string;
titleRow3Textfield: string;
selectedLogoAddressCard : LogoAddressCardModel;
constructor(
public previewDialog: MatDialog,
public errorDialog: MatDialog,
public nameDialog: MatDialog,
public logoDIalog: MatDialog,
private certHttpService: CertificateHttpService,
public snackBar: MatSnackBar,
private route: ActivatedRoute) { }
ngOnInit() {
console.log("On init called in create cert component!");
this.selectedLogoAddressCard = {
logo: "",
addressRow0: "Address row 0",
addressRow1: "Address row 1",
addressRow2: "Address row 2",
guid: Guid.create().toString()
};
this.disableDeleteButton = true;
this.isEditing = false;
this.resultRowWrappers = [];
this.propertyTextfield = "";
this.unitTextfield = "";
this.testResultTextfield = "";
this.route.queryParams.subscribe(params => {
try {
var certificate = JSON.parse(params["certificate"]);
this.editedCertificate = certificate;
this.fillInputFields(certificate);
this.selectedLogoAddressCard = certificate.logoAddressCard;
} catch{
console.log("CATCH: No cert in params.");
return;
}
});
}
openPreviewDialog(): void {
var newCertificate = this.createCertificateFromInputs(Guid.create().toString());
const dialogRef = this.previewDialog.open(PreviewDialogComponent, {
width: '30vw',
height: '99vh',
disableClose: false,
panelClass: "preview-dialog-container",
data: newCertificate
});
dialogRef.updatePosition({ top: '2px' });
dialogRef.afterClosed().subscribe(result => {
this.snackBar.dismiss();
});
}
openLogosDialog(): void {
const dialogRef = this.logoDIalog.open(LogosDialogComponent, {
width: '60vw',
height: '95vh',
disableClose: true,
panelClass: "logo-dialog-container"
});
dialogRef.updatePosition({top: "10px"});
var _this = this;
dialogRef.componentInstance.cardSelectedEvent.subscribe((res: AppCard) => {
_this.selectedLogoAddressCard = res.cardModel;
});
}
openErrorDialog(title: string, text: string) {
var data = {
"title": title,
"text": text
};
const dialogRef = this.errorDialog.open(ErrorDialogComponent, {
width: '30vw',
height: 'auto',
disableClose: true,
data: data
});
dialogRef.afterClosed().subscribe(result => {
console.log('The dialog was closed');
});
}
saveResultRowClicked() {
var newResultRow: ResultRow = {
property: this.propertyTextfield,
unit: this.unitTextfield,
testResult: this.testResultTextfield
};
var newResultRowWrapper: ResultRowWrapper = {
resultRow: newResultRow,
isChecked: false
}
this.resultRowWrappers.push(newResultRowWrapper);
this.propertyTextfield = "";
this.unitTextfield = "";
this.testResultTextfield = "";
}
deleteResultRowClicked() {
for (var i = 0; i < this.resultRowWrappers.length; i++)
if (this.resultRowWrappers[i].isChecked) {
this.resultRowWrappers.splice(i, 1);
i--;
}
}
saveClicked() {
var _this = this;
const dialogRef = this.nameDialog.open(CertNameDialogComponent, {
width: '40vw',
height: '37.5vh',
disableClose: true,
data: {
"currentName": ""
}
}).componentInstance.saveClickedEvent.subscribe(res => {
_this.newCertName = res;
_this.saveCertificate();
});
}
saveEditClicked() {
var _this = this;
const dialogRef = this.nameDialog.open(CertNameDialogComponent, {
width: '40vw',
height: '37.5vh',
disableClose: true,
data: {
"currentName": this.editedCertificate.name
}
}).componentInstance.saveClickedEvent.subscribe(res => {
_this.newCertName = res;
_this.overwriteCertificate();
});
}
saveCertificate() {
var newCertificate = this.createCertificateFromInputs(Guid.create().toString());
this.certHttpService.insertPro(newCertificate)
.then((res => {
this.nameDialog.closeAll();
this.openSnackBar("Saved certificate " + "\"" + newCertificate.name + "\"", "Close", "right", "bottom", 1*3000);
}).bind(this))
.catch(((error) => {
this.nameDialog.closeAll();
this.openErrorDialog("Error", error.name + ": " + error.message);
}).bind(this));
}
overwriteCertificate() {
var newCertificate = this.createCertificateFromInputs(this.editedCertificate.guid);
this.certHttpService.overwritePro(newCertificate)
.then((res => {
this.nameDialog.closeAll();
this.openSnackBar("Saved certificate " + "\"" + newCertificate.name + "\"", "Close", "right", "bottom", 1*3000);
}).bind(this))
.catch(((error) => {
this.nameDialog.closeAll();
this.openErrorDialog("Error", error.name + ": " + error.message);
}).bind(this));
}
createCertificateFromInputs(guid: string): CertificateModel {
var resultRows: ResultRow[] = [];
this.resultRowWrappers.forEach(e => {
resultRows.push(e.resultRow);
});
var certificate: CertificateModel = {
batchNumber: this.batchNumberTextfield,
certificateNo: this.certificateNoTextfield,
customer: this.customerTextfield,
customerArtNo: this.customerArtNoTextfield,
customerOrderNo: this.customerOrderNoTextfield,
date: this.dateTextfield,
deliveredQuantity: this.deliveredQuantityTextfield,
orderACKNNo: this.orderACKNNoTextfield,
specification: this.specificationTextfield,
resultRows: resultRows,
name: this.newCertName,
signature: this.signaturTextfield,
guid: guid,
titleRow0: this.titleRow0Textfield,
titleRow1: this.titleRow1Textfield,
titleRow2: this.titleRow2Textfield,
titleRow3: this.titleRow3Textfield,
logoAddressCard: this.selectedLogoAddressCard
};
return certificate;
}
previewClicked() {
this.openPreviewDialog();
this.openSnackBar("Click outside the preview dialog to close.", "Close", "right", "bottom", 24 * 60 * 60 * 1000);
}
fillInputFields(certificate: CertificateModel) {
this.isEditing = true;
// this.openSnackBar("Editing certificate " + "\"" + certificate.name + "\"", "Close", "right", "bottom", 5 * 1000);
this.resultRowWrappers = [];
if (certificate.resultRows != null)
if (certificate.resultRows.length > 0)
certificate.resultRows.forEach(e => {
var resultRow: ResultRowWrapper = {
resultRow: e,
isChecked: false
};
this.resultRowWrappers.push(resultRow);
});
this.customerArtNoTextfield = certificate.customerArtNo;
this.customerOrderNoTextfield = certificate.customerOrderNo;
this.customerTextfield = certificate.customer;
this.batchNumberTextfield = certificate.batchNumber;
this.certificateNoTextfield = certificate.certificateNo;
this.deliveredQuantityTextfield = certificate.deliveredQuantity;
this.dateTextfield = certificate.date;
this.orderACKNNoTextfield = certificate.orderACKNNo;
this.signaturTextfield = certificate.signature;
this.specificationTextfield = certificate.specification;
this.titleRow0Textfield = certificate.titleRow0;
this.titleRow1Textfield = certificate.titleRow1;
this.titleRow2Textfield = certificate.titleRow2;
this.titleRow3Textfield = certificate.titleRow3;
this.selectedLogoAddressCard = certificate.logoAddressCard;
}
openSnackBar(message: string, action: string, hPosition: string, vPosition: string, duration: number) {
this.snackBar.open(message, action, {
duration: duration,
horizontalPosition: hPosition as MatSnackBarHorizontalPosition,
verticalPosition: vPosition as MatSnackBarVerticalPosition
});
}
checkBoxClickedEvent() {
var areAnyChecked = false;
this.resultRowWrappers.forEach(e => {
if (e.isChecked) {
areAnyChecked = true;
return;
}
});
this.disableDeleteButton = !areAnyChecked;
}
selectCardClicked() {
this.openLogosDialog();
}
}
已使用的http服务的代码在导航后停止工作:
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { LogoAddressCardModel } from 'src/data_models/LogoAddressCardModel';
import { RequestOptions } from '@angular/http';
@Injectable({
providedIn: 'root'
})
export class LogoAddressCardHttpServiceService {
constructor(private httpClient: HttpClient) { }
getAllObs(): Observable<LogoAddressCardModel[]> {
return this.httpClient.get<LogoAddressCardModel[]>("http://localhost:50219/api/logo_address_card/get_all");
}
async getAllPro(): Promise<LogoAddressCardModel[]> {
var response = await this.getAllObs();
return response.toPromise();
}
insertObs(model: LogoAddressCardModel): Observable<any> {
console.log(model.addressRow0);
console.log(model.addressRow1);
console.log(model.addressRow2);
return this.httpClient.post<any>("http://localhost:50219/api/logo_address_card/insert", model);
}
async insertPro(model: LogoAddressCardModel): Promise<any> {
var response = await this.insertObs(model);
return response.toPromise();
}
overwriteObs(model: LogoAddressCardModel): Observable<any> {
return this.httpClient.post<any>("http://localhost:50219/api/logo_address_card/overwrite", model);
}
async overwritePro(model: LogoAddressCardModel): Promise<any> {
var response = await this.overwriteObs(model);
return response.toPromise();
}
deleteObs(model: LogoAddressCardModel): Observable<any> {
return this.httpClient.post<any>("http://localhost:50219/api/logo_address_card/delete", model);
}
async deletePro(model: LogoAddressCardModel): Promise<any> {
var response = await this.deleteObs(model);
return response.toPromise();
}
}
为什么相同的完全相同的http服务和http调用方法首先起作用,但后来却不起作用?我完全不知所措,想把自己的头发扯掉。
答案 0 :(得分:0)
使用NavigationExtras的问题是在发出HTTP请求时将它们添加到URL。这就是导致错误请求的原因。 API控制器在URL中有很多意外的参数。