简体   繁体   English

HTTP 获取请求 SQL 服务器 web ZDB974238714CA8DE634A7CE1D083A14

[英]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.我正在我的网站后端工作,我需要从我的 SQL 服务器获取特定信息。

For this I use the HTTP Get request.为此,我使用 HTTP 获取请求。 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.但我不想使用 ID 来获取信息,但我想键入一个名称以在数据库中搜索该名称。

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.当我将它改回 ID 时,我可以搜索 ID,它会返回我想要的信息。

How do I make a correct HTTP get request for my Tool Name?如何对我的工具名称提出正确的 HTTP 请求?

Edit:编辑:

More information about the model:有关 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. Tool_Registration 是表的名称。 The module exists of the column names.模块存在的列名。

Edit 2:编辑2:

This is my complete controller:这是我完整的 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. Entity Framework 的FindAsync方法根据主键返回一行。 When you change the input from the ID to Tool_Name you are no longer passing the method the primary key.当您将输入从 ID 更改为Tool_Name时,您不再向该方法传递主键。 Thus you need to use another EF method such as FirstOrDefault to return the details based on the Tool_Name:因此,您需要使用其他 EF 方法(例如FirstOrDefault )根据 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:您还应该实现两个端点:一个基于 ID 返回单个用户记录,另一个基于 Tool_Name 过滤器返回多个:

[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:文档中,asp.net MVC 中的默认路由约定是:

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.这可以将ID参数理解为路径的一部分。 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.当参数名称更改时,这不是路由的一部分,因此框架无法识别 Tool_Name 路径段应被解释为操作参数。

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");

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

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