簡體   English   中英

Angular 7 和 .NET Core API 中不支持的媒體類型 415 錯誤

[英]Unsupported Media Type 415 Error in Angular 7 & .NET Core API

我正在使用材料數據表上的選擇傳入要在我的 Angular 應用程序中刪除的選定行。 但出於某種原因,我收到了 415 錯誤。 不確定我在服務器端還是客戶端做錯了什么,但我不確定即使我傳遞了正確的對象。

這里有什么問題? 我正在為客戶端使用 Angular 7 並在 .NET Core 中制作 API

ActionsController.cs .NET 核心

 [HttpDelete("deleteRow")]
    public Msg DeleteRows(string sessionId, T table, Tag[] rows)
    {
        try
        {
            UserState userState = GetUserState(sessionId);

            Msg m = CheckTableAccess(sessionId, table, TableAccessLevel.ReadModifyCreateDelete, userState);

            if (m.IsNotOk)
                return m;

            if (table == T.Action)
            {
                foreach (Tag t in rows)
                {
                    m = CheckUpdatableAction(sessionId, rows[0]);
                    if (m.IsNotOk)
                        return m;
                }
            }

            if (table == T.RouteStop)
            {
                XioTransaction xt = new XioTransaction(userState);
                XioWriter xwd = null;
                xwd = xt.CreateDeleteWriter(table);
                foreach (Tag t in rows)
                {
                    XioTable routeStop = new XioTable(userState, T.RouteStop);
                    Tag ownerTag = ((DbrRouteStop)routeStop.LoadSingleRow(t, C.RouteStop_RouteTag)).RouteTag;
                    xwd.DeleteRow(t, ownerTag);
                }
                xt.WriteAll();
            }
            else if (table == T.RouteEvent)
            {
                XioTransaction xt = new XioTransaction(userState);
                XioWriter xwd = null;
                xwd = xt.CreateDeleteWriter(table);

                foreach (Tag t in rows)
                {
                    XioTable routeEvent = new XioTable(userState, T.RouteEvent);
                    Tag ownerTag = ((DbrRouteEvent)routeEvent.LoadSingleRow(t, C.RouteEvent_RouteTag)).RouteTag;
                    xwd.DeleteRow(t, ownerTag);
                }
                xt.WriteAll();
            }
            else if (table == T.CompanyResource)
            {
                XioTransaction xt = new XioTransaction(userState);
                XioWriter xwd = null;
                xwd = xt.CreateDeleteWriter(table);

                foreach (Tag t in rows)
                {
                    XioTable cr = new XioTable(userState, T.CompanyResource);
                    DbrCompanyResource crRec = (DbrCompanyResource)cr.LoadSingleRow(t, C.CompanyResource_CompanyTag, C.CompanyResource_Tab);

                    XioTable xtr = new XioTable(userState, crRec.Tab);
                    // the critical where is on divisiontag and all tables that are passed in will have a divion tag
                    // luckily the code will just look at the field name
                    xtr.WhereList.Where(C.Driver_DivisionTag, ComparisonOp.EqualTo, crRec.CompanyTag);
                    xtr.LoadData();
                    if (xtr.GetAllRows().Length > 0)
                        return new Msg(M.ResourcesExistAtCompanyLevel);
                    xwd.DeleteRow(t);
                }
                xt.WriteAll();
            }
            else
                DbRow.DeleteRecursive(userState, table, rows);

            userState.Completed(LogEntryType.DeleteRows, null);
        }
        catch (MsgException e)
        {
            return e.Msg;
        }

        catch (SqlException e)
        {
            if (e.Number == 547)
            {
                return new Msg(M.CannotDeleteOwnerRowWithComponent);
            }
            else
                return new Msg(M.UnexpectedViewDeleteError, e.ToString());
        }
        catch (Exception e)
        {
            return new Msg(M.UnexpectedViewDeleteError, e.ToString());
        }

        return Msg.Ok;
    }

視圖組件.ts

    export class ViewComponent implements OnInit, OnDestroy {

  // User Fields
  currentUser: User;
  users: User[] = [];
  currentUserSubscription: Subscription;

  loading : boolean;
  // Action Fields
  viewData: any;
  viewName: string;
  refNumber: number;
  currentActionSubscription: Subscription;
  displayedColumns: string[] = [];
  dataSource: any = new MatTableDataSource([]);
  pageSizeOptions: number[] = [10, 20, 50];

  @ViewChild(MatSort) sort: MatSort;
  @ViewChild(MatPaginator) paginator: MatPaginator;

  selection = new SelectionModel<TableRow>(true, []);

  defaultSort: MatSortable = {
    id: 'defColumnName',
    start: 'asc',
    disableClear: true
  };

  defaultPaginator: MatPaginator;

  constructor(
    private iconRegistry: MatIconRegistry,
    private sanitizer: DomSanitizer,
    private actionService: ActionService
  ) {
    this.loading = false;
    this.iconRegistry.addSvgIcon(
      'thumbs-up',
      this.sanitizer.bypassSecurityTrustResourceUrl(
        'assets/img/examples/thumbup-icon.svg'
      )
    );
  }

  loadAction(action: any) {

    this.loading = true;
    // If there is already data loaded into the View, cache it in the service.
    if (this.viewData) {
      this.cacheAction();
    }

    if (this.sort) {
      // If there is sorting cached, load it into the View.
      if (action.sortable) {
        // If the action was cached, we should hit this block.
        this.sort.sort(action.sortable);
      } else {
        // Else apply the defaultSort.
        this.sort.sort(this.defaultSort);
      }
    }

    if (this.paginator) {
      // If we've stored a pageIndex and/or pageSize, retrieve accordingly.
      if (action.pageIndex) {
        this.paginator.pageIndex = action.pageIndex;
      } else { // Apply default pageIndex.
        this.paginator.pageIndex = 0;
      }

      if (action.pageSize) {
        this.paginator.pageSize = action.pageSize;
      } else { // Apply default pageSize.
        this.paginator.pageSize = 10;
      }
    }

    // Apply the sort & paginator to the View data.
    setTimeout(() => this.dataSource.sort = this.sort, 4000);
    setTimeout(() => this.dataSource.paginator = this.paginator, 4000);

    // Load the new action's data into the View:
    this.viewData = action.action;
    this.viewName = action.action.ActionName;
    this.refNumber = action.refNumber;

    // TODO: add uniquifiers/ids and use these as the sort for table

    const displayedColumns = this.viewData.Columns.map((c: { Name: any; }) => c.Name);
    displayedColumns[2] = 'Folder1';
    this.displayedColumns = ['select'].concat(displayedColumns);
    // tslint:disable-next-line: max-line-length
    const fetchedData = this.viewData.DataRows.map((r: { slice: (arg0: number, arg1: number) => { forEach: (arg0: (d: any, i: string | number) => any) => void; }; }) => {
      const row = {};
      r.slice(0, 9).forEach((d: any, i: string | number) => (row[this.displayedColumns[i]] = d));
      return row;
    });

    this.dataSource = new MatTableDataSource(fetchedData);
    this.loading = false;
  }

  // Stores the current Action, sort, and paginator in an ActionState object to be held in the action service's stateMap.
  cacheAction() {
    let actionState = new ActionState(this.viewData);

    // Determine the sort direction to store.
    let cachedStart: SortDirection;
    if (this.sort.direction == "desc") {
      cachedStart = 'desc';
    } else {
      cachedStart = 'asc';
    }

    // Create a Sortable so that we can re-apply this sort.
    actionState.sortable = {
      id: this.sort.active,
      start: cachedStart,
      disableClear: this.sort.disableClear
    };

    // Store the current pageIndex and pageSize.
    actionState.pageIndex = this.paginator.pageIndex;
    actionState.pageSize = this.paginator.pageSize;

    // Store the refNumber in the actionState for later retrieval.
    actionState.refNumber = this.refNumber;
    this.actionService.cacheAction(actionState);
  }

  ngOnInit() {
    // Subscribes to the action service's currentAction, populating this component with View data.
    this.actionService.currentAction.subscribe(action => this.loadAction(action));
  }

    /** Whether the number of selected elements matches the total number of rows. */
    isAllSelected() {
      const numSelected = this.selection.selected.length;
      const numRows = this.dataSource.data.length;
      return numSelected === numRows;
    }

    /** Selects all rows if they are not all selected; otherwise clear selection. */
    masterToggle() {
      this.isAllSelected()
        ? this.selection.clear()
        : this.dataSource.data.forEach((row: TableRow) => this.selection.select(row));
    }

    // Delete row functionality

    deleteRow() {
      console.log(this.selection);
      this.selection.selected.forEach(item => {
        const index: number = this.dataSource.data.findIndex((d: TableRow) => d === item);
        console.log(this.dataSource.data.findIndex((d: TableRow) => d === item));
        this.dataSource.data.splice(index, 1);
        this.dataSource = new MatTableDataSource<Element>(this.dataSource.data);
      });
      this.selection = new SelectionModel<TableRow>(true, []);
      this.actionService.deleteRow(this.selection).subscribe((response) => {
        console.log('Success!');
      });
    }

動作服務.ts

  deleteRow(selection: any): Observable<{}> {
    console.log('testing service');
// create an array of query params using the property that you use to identify a table row
    const queryParams = [selection._selection].map((row: { value: any; }) => `id=${row.value}`);
// add the query params to the url
    const url = `http://localhost:15217/actions/deleteRow`;
    return this.http.delete<any>(url);
  }

您需要添加一個 http 標頭來指定 http 請求正文的內容類型。 如果您發送的是 json 正文,則標頭為content-type: application/json

您可以更新actionService.ts

deleteRow(selection: any): Observable<{}> {

    let headers = new Headers();
    headers.append('Content-Type', 'application/json');
    const queryParams = [selection._selection].map((row: { value: any; }) => `id=${row.value}`);
    const url = `http://localhost:15217/actions/deleteRow`;

    const options = {
        headers: new HttpHeaders({
            'Content-Type': 'application/json'
        }),
        body: {}
    } 

    return this.http.delete<any>(url, options);
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM