저는 asp.net 코어 3.0과 Reactjs 웹 애플리케이션을 작성했습니다. 내 API에 게시 할 때 문제가 있습니다. 메서드에 맞지만 인수는 항상 null입니다.
디버깅했고 반응 앱에서 데이터를 보았습니다.
DELETE 메서드를 호출 할 때 아무런 문제가 없습니다.
CQRS + MediatR 패턴을 사용하고 있지만 단순화하기 위해 Cqrs + MediatR의 일부를 제거하고 ActivityConroller에 코드를 추가했습니다. 양식을 처리하기 위해 Formik 라이브러리를 사용했으며 웹 앱의 템플릿을 만들기 위해 Ant Design을 사용했습니다.
백엔드 :
[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>
);
};
agent.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 };
App.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 형식의 요청 본문은 JsonInputFormatter
및 System.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
이면 작동하지 않습니다. 클라이언트 측에서 형식을 변경하거나 쿼리 문자열을 통해 보내거나 (공백없이 요청이 구성되었는지 확인) 경로 값의 일부로 보낼 수 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다