繁体   English   中英

为什么来自 Reactjs 的 post 参数始终为 null asp.net core web API?

[英]Why post parameter is always null asp.net core web API from Reactjs?

我写了一个 asp.net core 3.0 和 Reactjs web 应用程序。 我在 POST 到我的 api 时遇到问题。 它击中了方法,但参数始终为空。

我已经调试并在反应应用程序中看到了数据。

当我调用 DELETE 方法时,我没有任何问题。

我正在使用 CQRS + MediatR 模式,但为了简化,我删除了 Cqrs + MediatR 的一部分,并在 ActivityConroller 中添加了我的代码。 请注意,我使用 Formik 库处理表单,还使用 ​​Ant Design 创建 Web 应用程序模板。

后端:

     [Route("api/[controller]")]
     public class ActivitiesController : ControllerBase
     {        
         private readonly DataContext _context;

         public Handler(DataContext context)
         {
             _context = context;
         }

         [HttpPost]
         public async Task<ActionResult> Create(Activity model)
         {
             var activity = new Activity
             {
                 Id = model.Id,
                 Title = model.Title,
                 Description = model.Description,
                 Category = model.Category,
                 Date = model.Date,
                 City = model.City,
                 Venue = model.Venue
             };

             _context.Activities.Add(activity);

             var success = await _context.SaveChangesAsync() > 0;

             if (success) return Ok();

             throw new Exception("Problem saving changes");
         }        
    }

----------
ActivityForm.tsx

import React, { useState, FormEvent } from "react";
import { Formik, FormikProps, Field } from "formik";
import { Button, Input, Form, Card, DatePicker } from "antd";
import FormItem from "antd/lib/form/FormItem";
import { IActivity } from "../../../app/models/activity";
import moment, { Moment } from "moment";
import "moment/locale/en-au";
import { v4 as uuid } from "uuid";
const { TextArea } = Input;

interface IProps {
  setEditMode: (arg: boolean) => void;
  activity: IActivity;
  createActivity: (activity: IActivity) => void;
  editActivity: (activity: IActivity) => void;
}

export const ActivityForm: React.FC<IProps> = (prop: IProps) => {
  const initialValues = () => {
    if (prop.activity) {
      return prop.activity;
    } else {
      return {
        id: "",
        title: "",
        category: "",
        description: "",
        city: "",
        date: "",
        venue: ""
      };
    }
  };
  const [activity, setActivity] = useState<IActivity>(initialValues);
  const [chooseDate, setChooseDate] = useState();
  // const defaultValue = moment().format("YYYY/MM/DD HH:mm:ss");
  const onChange = (date: Moment | null, dateString: string) => {
    let dateSelected = date;
    setChooseDate(dateSelected);
  };
  const handleInputChange = (
    event: FormEvent<HTMLInputElement | HTMLTextAreaElement>
  ) => {
    const { name, value } = event.currentTarget;
    setActivity({ ...activity, [name]: value });
  };
  const handleSubmit = (e: FormEvent) => {
    e.preventDefault();
    if (activity.id.length === 0) {
      let newActivity = { ...activity, id: uuid() };
      newActivity.date = moment(chooseDate).format("YYYY-MM-DD HH:mm:ss");
      console.log(newActivity);
      prop.createActivity(newActivity);
    } else {
      prop.editActivity(activity);
    }
  };
  return (
    <div>
      <Formik
        initialValues={initialValues}
        onSubmit={(values, actions) => {

        }}
        render={() => (
          <Form style={{ marginTop: 100 }} onSubmit={handleSubmit}>
            <Field
              render={(props: IProps & FormikProps<IProps>) => (
                <Card style={{ width: 400 }}>
                  <FormItem>
                    <Input
                      value={activity.title}
                      placeholder="Title"
                      onChange={handleInputChange}
                      name="title"
                      type="text"
                    />

                    <TextArea
                      // {...props.description}
                      value={activity.description}
                      placeholder="Description"
                      onChange={handleInputChange}
                      rows={4}
                      name="description"
                    />

                    <Input
                      value={activity.category}
                      placeholder="Category"
                      onChange={handleInputChange}
                      name="category"
                      type="text"
                    />

                    <DatePicker
                      showTime={{
                        defaultValue: moment("00:00:00", "HH:mm:ss")
                      }}

                      style={{ width: 350 }}
                      onChange={() => onChange}
                      name="date"
                      format="YYYY-MM-DD HH:mm:ss"
                    />

                    <Input
                      value={activity.city}
                      placeholder="City"
                      onChange={handleInputChange}
                      name="city"
                      type="text"
                    />

                    <Input
                      value={activity.venue}
                      placeholder="Venue"
                      onChange={handleInputChange}
                      name="venue"
                      type="text"
                    />
                  </FormItem>

                  <div>
                    <Button htmlType="submit" type="primary" size="large">
                      Submit
                    </Button>
                    <Button
                      onClick={() => prop.setEditMode(false)}
                      type="ghost"
                      size="large"
                      style={{ marginLeft: 10 }}
                    >
                      Cancel
                    </Button>
                  </div>
                </Card>
              )}
            />
          </Form>
        )}
      />
    </div>
  );
};

代理.ts

import axios, { AxiosResponse } from "axios";
import { IActivity } from "../models/activity";

axios.defaults.baseURL = "http://localhost:5000/api";

const responseBody = (response: AxiosResponse) => response.data;

const requests = {
  get: (url: string) => axios.get(url).then(responseBody),
  post: (url: string, body: {}) =>
    axios.post(url, body).then(responseBody),
  put: (url: string, body: {}) => axios.put(url, body).then(responseBody),
  del: (url: string) => axios.delete(url).then(responseBody)
};

const Activities = {
  list: (): Promise<IActivity[]> => requests.get("/activities"),
  details: (id: string) => requests.get(`/activities/${id}`),
  create: (activity: IActivity) => requests.post("/activities", activity),
  update: (activity: IActivity) =>
    requests.put(`/activities/${activity.id}`, activity),
  delete: (id: string) => requests.del(`/activities/${id}`)
};

export default { Activities };

应用程序.tsx

import React, { useEffect, useState, Fragment } from "react";
import { IActivity } from "../models/activity";
import { NavBar } from "../../features/nav/NavBar";
import { ActivityDashboard } from "../../features/activities/dashboard/ActivityDashboard";
import "./styles.css";
import agent from "../api/agent";

function App() {
  const [activities, setActivities] = useState<IActivity[]>([]);
  const [selectedActivity, setSelectedActivity] = useState<IActivity | null>(
    null
  );

  const handleSelectActivity = (id: string) => {
    setSelectedActivity(activities.filter(a => a.id === id)[0]);
    setEditMode(false);
  };
  const [submitting, setSubmitting] = useState(false);
  const handleOpenCreateForm = () => {
    setSelectedActivity(null);
    setEditMode(true);
  };


  const handleCreateActivity = (activity: IActivity) => {
    agent.Activities.create(activity)
      .then(() => {
        setActivities([...activities, activity]);
        setSelectedActivity(activity);
        setEditMode(false);
      })
      .catch(error => {
        console.log(error.response);
      });
  };

  const handleEditActivity = (activity: IActivity) => {
    setActivities([...activities.filter(a => a.id !== activity.id), activity]);
    setSelectedActivity(activity);
    setEditMode(false);
  };

  const handleDeleteActivity = (id: string) => {
    agent.Activities.delete(id)
      .then(() => {
        setActivities([...activities.filter(a => a.id !== id)]);
      })
      .catch(error => {
        console.log(error.response);
      });
  };

  const [editMode, setEditMode] = useState(false);

  useEffect(() => {
    async function fetchData() {
      agent.Activities.list().then(response => {
        let activities: IActivity[] = [];
        response.forEach(activity => {
          activity.date = activity.date.split(".")[0];
          activities.push(activity);
        });
        setActivities(activities);
      });
    }
    fetchData();
  }, []);

  return (
    <Fragment>
      <NavBar openCreateForm={handleOpenCreateForm} />

      <ActivityDashboard
        activities={activities}
        selectActivity={handleSelectActivity}
        selectedActivity={selectedActivity}
        editMode={editMode}
        setEditMode={setEditMode}
        setSelectedActivity={setSelectedActivity}
        createActivity={handleCreateActivity}
        editActivity={handleEditActivity}
        deleteActivity={handleDeleteActivity}
      />
    </Fragment>
  );
}

export default App;

使用[FromBody] ,JSON 格式的请求正文由JsonInputFormatterSystem.Text.Json (asp.net core 3.0) 处理,因此JSON 格式正确的 DateTime 值将起作用:

在此处输入图片说明

文档链接: https : //docs.microsoft.com/en-us/dotnet/standard/datetime/system-text-json-support

因此,如果您从客户端发送的字符串格式YYYY-MM-DD HH:mm:ss ,那将不起作用。 您可以在客户端更改格式,或者您可以通过查询字符串发送(确保请求没有空格)或作为路由值的一部分发送。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM