Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
161 views
in Technique[技术] by (71.8m points)

c# - Error when using api call to send post values to controller and mapping them with a dto

I have two webpages, the first has a dropdown that allows the person to select a project & a button. When the button is submitted, it takes them to the manage users webpage and sends the Projectname to the webpage as well. The manage users webpage allows the person to assign a user to the project they selected on the previous webpage. There is a button as well, and when submitted it sends an api call with post values to my controller. The controller accepts a dto and then binds these values to the AssignUserDto. It then finds the entity associated w/ the dto username, and then maps the values from the dto to the entity so that the user has a Projectname associated with it.

It gives the error Cannot insert the value NULL into column 'description', table 'IssueTrackerDB.dbo.Projects'; column does not allow nulls. INSERT fails. The statement has been terminated. I have another post action that creates a project in the same controller, so I'm wondering if that post action is interfering with the AddUser action. Also, if I comment out the post action that creates the project and run it, it doesn't give that error anymore. I'm receiving a 405 Method Not Allowed error. Another question is how to differentiate between the two post actions so that it doesn't give that error.

Controller - Add User Action

[HttpPost("adduser")]
        public ActionResult AddUser([FromBody] AssignUserDto assignUserDto)
        {
            Users user = _repository.GetUserByName(assignUserDto.username);
            _mapper.Map(assignUserDto, user);
            _repository.SaveChanges();
            return NoContent();
        }

Controller - Create Project Action

// POST api/values
        [HttpPost]
        public void Post([FromBody] Projects project)
        {
            _repository.CreateProject(project);
            _repository.SaveChanges();
        }

AssignUserDto

using System;
using System.ComponentModel.DataAnnotations;

namespace IssueTracker.Dtos
{
    public class AssignUserDto
    {
        [Required]
        public string username { get; set; }

        [Required]
        public string Projectsname { get; set; }

        public AssignUserDto(string username, string Projectsname)
        {
            this.username = username;
            this.Projectsname = Projectsname;
        }
    }
}

Users Model

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace IssueTracker.Models
{
    public class Users
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int id { get; set; }

        [Required]
        public string username { get; set; }

        [Required]
        public string password { get; set; }

        [Required]
        public string email { get; set; }

        [Required]
        public string role { get; set; }

        public string? Projectsname { get; set; }

        [ForeignKey("Projectsname")]
        public virtual Projects Projects { get; set; }

        public Users(string username, string password, string email, string role)
        {
            this.username = username;
            this.password = password;
            this.email = email;
            this.role = role;
        }

        public Users()
        {

        }

    }
}

Projects Model

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace IssueTracker.Models
{
    public class Projects
    {
        public Projects(string name, string description)
        {
            this.name = name;
            this.description = description;
        }

        public Projects()
        {

        }

        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public string id { get; set; }

        [Required]
        public string name { get; set; }

        [Required]
        public string description { get; set; }

        
    }
}

project.js

import React, { Component } from "react";
import { useState, useEffect } from "react";
import { Grid, TextField, Button, Typography } from "@material-ui/core";
import {
    BrowserRouter as Router,
    Link,
    Route,
    Switch,
} from 'react-router-dom';
import Select from 'react-select';

const Project = () => {
    const [name, setName] = useState();
    const [description, setDescription] = useState();
    const [projects, setProjects] = useState([]);
    const [selectedValue, setSelectedValue] = useState();
    const [selectedLabel, setSelectedLabel] = useState();
    const projectlist = [];

    const handleChange = obj => {
        setSelectedValue(obj.value);
        setSelectedLabel(obj)
    }

    const post = () => {
        const requestOptions = {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
                name: name,
                description: description,
            }),
        };
        fetch("/api/Project", requestOptions)
            .then((response) => response.json())
            .then((data) => {

            })
    }

    useEffect(() => {
        fetch("/api/Project")
            .then((response) => response.json())
            .then((data) => {
                setProjects(data)
            })
    }, [])

    return (
        <div>
            {projects.forEach(function (element) {
                projectlist.push({ label: element.name, value: element.name })
            })}e
            {console.log(selectedValue)}
            <body>
                <Select
                    value={selectedLabel}
                    options={projectlist}
                    onChange={handleChange}
                    isOptionDisabled={option => option.isDisabled}
                />
                <form action="#" method="POST">
                    <TextField onChange={(e) => setName(e.target.value)}> </TextField>
                    <br>
                    </br>
                    <TextField onChange={(e) => setDescription(e.target.value)}> </TextField>
                    <br>
                    </br>
                    <Button onClick={() => post()}> Create New Project </Button>
                </form>
            </body>
            <Link to={{
                pathname: '/manageusers',
                state: {
                    project_name: selectedValue
                }
            }}>Manage Users
          </Link>
        </div>
    );
}



export default Project;

manageusers.js

import React, { Component } from "react";
import { useState, useEffect } from "react";
import { Grid, TextField, Button, Typography } from "@material-ui/core";
import { FixedSizeList as List } from 'react-window';
import css from './style.css';
import Select from 'react-select';
import { useLocation } from "react-router";

const Manageusers = () => {
    const [role, setRole] = useState([]);
    const location = useLocation();
    const [project_name, setProjectName] = useState();
    const [selectedValue, setSelectedValue] = useState();
    const rolelist = [];
    const [selectedLabel, setSelectedLabel] = useState();

    const handleChange = obj => {
        setSelectedValue(obj.value);
        setSelectedLabel(obj);
    }

    useEffect(() => {
        fetch("/api/IssueTracker")
            .then((response) => response.json())
            .then((data) => {
                setRole(data)
            })
    }, [])

    const post = () => {
        const requestOptions = {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
                username: selectedValue,
                Projectsname: project_name
            }),
        };
        fetch("/api/Project", requestOptions)
            .then((response) => response.text())
            .then((data) => {

            })
            .catch((error) => {
                console.log(error)
            });
    }

    const Name = () => {
        return (
            <div>
                <Grid item xs={3}>
                    <Typography component="h5" variant="h5">
                        {setProjectName(location.state.project_name)}
                    </Typography>
                </Grid>
            </div>
        )

    }

    return (
        <div>
            {role.forEach(function (element) {
                rolelist.push({ label: element.username, value: element.username })
            })}
            {console.log(selectedValue)}

            <Select name="user"
                value={selectedLabel}
                options={rolelist}
                onChange={handleChange}
                isOptionDisabled={option => option.isDisabled}
            />
            <div>
                <Button onClick={() => post()}> Add User</Button>
            </div>
            <Name />
        </div>
    );
}

export default Manageusers;
question from:https://stackoverflow.com/questions/65929192/error-when-using-api-call-to-send-post-values-to-controller-and-mapping-them-wit

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your const post in manageusers.js has the wrong route. You're targeting "/api/Project" when it should probably be "/api/Project/adduser".

It looks like you are hitting the POST "/api/Project" method, it tries to insert a new Projects into the database and fails when it is missing fields. You get the 405 when you remove that method because after you remove it, there is no longer a valid POST "/api/Project"


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...