简体   繁体   中英

HTTP Get request SQL server web API

I am working on the backend of my website and I need to get specific information from my SQL Server.

For this I use the HTTP Get request. But I don't want to use the ID to get the information, but I want to type a name to search the database for that name.

This is my current code:

// GET: api/Users/Toolname
    [HttpGet]
    public async Task<ActionResult<Users>> Get(string Tool_Name)
    {
        var info = await _context.Tool_Registration.FindAsync(Tool_Name);

        if (info == null)
        {
            return info;
        }

        return info;
    }

So when I enter a Tool name it should return all the information where the Tool name is used. But it doesn't return anything. When I change it back to ID then I can search for the ID and it returns the information I want.

How do I make a correct HTTP get request for my Tool Name?

Edit:

More information about the model:

public class Users
{
    [Key]
    public int Tool_ID { get; set; }
    [Required]
    [Column(TypeName = "varchar(MAX)")]
    public string Tool_Name { get; set; }

    [Column(TypeName = "int")]
    public int UUID { get; set; }

    [Column(TypeName = "varchar(MAX)")]
    public string Name { get; set; }

    [Column(TypeName = "varchar(MAX)")]
    public string Surname { get; set; }

}

Tool_Registration is the name of the table. The module exists of the column names.

Edit 2:

This is my complete controller:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using iTools_Web_API.Models;

namespace iTools_Web_API.Controllers
{



 [Route("api/[controller]")]
    [ApiController]
    public class UsersController : ControllerBase
{
    private readonly UsersContext _context;

    public UsersController(UsersContext context)
    {
        _context = context;
    }

    [HttpGet]
    [Route("api/Users/{UserId}")]
    public async Task<ActionResult<Users>> GetUserById(int UserId)
    {
        var user = await _context.Tool_Registration.FindAsync(UserId);
        return Ok(user);
    }

    [HttpGet]
    [Route("api/Users/")]
    public async Task<ActionResult<IEnumerable<Users>>> GetUsers(string Tool_Name)
    {
        IEnumerable<Users> users;
        if (string.IsNullOrEmpty(Tool_Name))
            users = await _context.Tool_Registration.ToListAsync();
        else
            users = await _context.Tool_Registration.Where(tr => tr.Tool_Name == Tool_Name).ToListAsync();
        return Ok(users);
    }

    // PUT: api/Users/5
    // To protect from overposting attacks, enable the specific properties you want to bind to, for
    // more details, see https://go.microsoft.com/fwlink/?linkid=2123754.
    [HttpPut("{id}")]
    public async Task<IActionResult> PutUsers(int id, Users users)
    {
        if (id != users.Tool_ID)
        {
            return BadRequest();
        }

        _context.Entry(users).State = EntityState.Modified;

        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!UsersExists(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return NoContent();
    }

    // POST: api/Users
    // To protect from overposting attacks, enable the specific properties you want to bind to, for
    // more details, see https://go.microsoft.com/fwlink/?linkid=2123754.
    [HttpPost]
    public async Task<ActionResult<Users>> PostUsers(Users users)
    {
        var Tool = await _context.Tool_Registration.FindAsync(users.Tool_Name);
        if(Tool != null)
        {
            return Tool;
        }
        else
        {
            return NotFound();
        }
    }

    // DELETE: api/Users/5
    [HttpDelete("{id}")]
    public async Task<ActionResult<Users>> DeleteUsers(int id)
    {
        var users = await _context.Tool_Registration.FindAsync(id);
        if (users == null)
        {
            return NotFound();
        }

        _context.Tool_Registration.Remove(users);
        await _context.SaveChangesAsync();

        return users;
    }

    private bool UsersExists(int id)
    {
        return _context.Tool_Registration.Any(e => e.Tool_ID == id);
    }
}
}

Entity Framework's FindAsync method returns a row based on a primary key. When you change the input from the ID to Tool_Name you are no longer passing the method the primary key. Thus you need to use another EF method such as FirstOrDefault to return the details based on the Tool_Name:

var info = await _context.Tool_Registration.FirstOrDefaultAsync( tr => tr.Tool_Name == Tool_Name);

You should also probably implement two endpoints: one to return a single User record based on the ID, and one to return multiple based on the Tool_Name filter:

[HttpGet]
[Route("{UserId}")]
public async Task<ActionResult<Users>> GetUserById(int UserId)
{
    var user = await _context.Tool_Registration.FindAsync(UserId);
    return Ok(user);
}

[HttpGet]
[Route("")]
public async Task<ActionResult<IEnumerable<Users>>> GetUsers(string Tool_Name)
{
    IEnumerable<Users> users;
    if (string.IsNullOrEmpty(Tool_Name))
        users = await _context.Tool_Registration.ToListAsync();
    else
        users = await _context.Tool_Registration.Where(tr => tr.Tool_Name == Tool_Name).ToListAsync();
    return Ok(users);
}

This is probably a routing issue. From the documentation the default routing convention in asp.net MVC is:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
});

This gives comprehension of the ID parameter as part of the path. When the parameter name is changed this is not part of the route, so the framework doesn't recognise that the Tool_Name path segment should be interpreted as an action parameter.

Requesting your new action in the form:

GET /api/Users?Tool_Name=toolname 

should get you the right result, alternatively/additionally you can add another route:

endpoints.MapControllerRoute(
        name: "Tool_Name",
        pattern: "{controller=Users}/{action=Get}/Tool_Name");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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