【问题标题】:What is the correct URI to call controller in web api in c#?在 c# 的 web api 中调用控制器的正确 URI 是什么?
【发布时间】:2016-08-31 22:52:33
【问题描述】:

我的控制器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using MySql.Data;
using MySql.Data.MySqlClient;
using System.Data;
using System.Configuration;

namespace WebAPIDemo.Controllers
{
    public class WebAPIDemoController : ApiController
    {           
        public class Users
        {
            string connectionstring = ConfigurationManager.ConnectionStrings["MySqlConnectionString"].ConnectionString.ToString();
            MySqlDataReader reader = null;
            MySqlConnection connection;

            public int Id;
            public string FirstName;

            [ActionName("GetUser")]
            [Route("api/WebAPIDemo/GetUserById")]

            [HttpGet]
            public Users GetUserById(int UserId)
            {       
                using (connection = new MySqlConnection(connectionstring))
                {     
                    MySqlCommand sqlCmd = new MySqlCommand();
                    sqlCmd.CommandType = CommandType.Text;
                    sqlCmd.CommandText = "Select * from User where id='"+ UserId + "' ";
                    sqlCmd.Connection = connection;
                    connection.Open();
                    reader = sqlCmd.ExecuteReader();
                    Users usr = new Users();
                    while (reader.Read())
                    {    
                        usr.FirstName = (Convert.IsDBNull(reader["FirstName"]) ? "" : Convert.ToString(reader["FirstName"]));
                        connection.Close();
                    }
                    return usr;                    
                 }
            }    
        }
    }
}

web api 配置路由

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using Microsoft.Owin.Security.OAuth;
using Newtonsoft.Json.Serialization;

namespace WebAPIDemo
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            // Configure Web API to use only bearer token authentication.
            //config.SuppressDefaultHostAuthentication();
            //config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

            // Web API routes
            config.MapHttpAttributeRoutes();



            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new {id = RouteParameter.Optional }
            );
        }
    }
}

URI

http://localhost:53869/api/WebAPIDemo/GetUserById?id=96

错误信息

<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://localhost:53869/api/WebAPIDemo/GetUserById?id=96'.
</Message>
<MessageDetail>
No action was found on the controller 'WebAPIDemo' that matches the request.
</MessageDetail>
</Error>

我是 web api 的新手 .. 身体能帮忙吗... 我找不到什么错误... 我已经阅读了一些谷歌的文章,但无法解决.......

【问题讨论】:

  • 感谢 rboe ..... 但是即使在 WebAPIDemoController 中移动方法之后......仍然有错误......
  • 要么将查询字符串更新为?UserId=96,要么将操作参数更改为id。他们需要匹配才能匹配路由。
  • 请把[Route("~")]放在你的控制器上。

标签: c# asp.net-web-api2


【解决方案1】:

您的操作方法不在控制器内部;它在Users 类中。上移一层,应该可以找到(必须是WebAPIDemoController的方法)。对于这个例子,我从控制器中提取了Users 类。

public class Users
{        
    public int Id;
    public string FirstName;
}

public class WebAPIDemoController : ApiController
{               
    [ActionName("GetUser")]
    [Route("api/WebAPIDemo/GetUserById")]

    [HttpGet]
    public Users GetUserById(int UserId)
    {       
        string connectionstring = ConfigurationManager.ConnectionStrings["MySqlConnectionString"].ConnectionString.ToString();
        MySqlDataReader reader = null;
        MySqlConnection connection;

        using (connection = new MySqlConnection(connectionstring))
        {     
            MySqlCommand sqlCmd = new MySqlCommand();
            sqlCmd.CommandType = CommandType.Text;
            sqlCmd.CommandText = "Select * from User where id='"+ UserId + "' ";
            sqlCmd.Connection = connection;
            connection.Open();
            reader = sqlCmd.ExecuteReader();
            Users usr = new Users();
            while (reader.Read())
            {    
                usr.FirstName = (Convert.IsDBNull(reader["FirstName"]) ? "" : Convert.ToString(reader["FirstName"]));
                connection.Close();
            }
            return usr;                                     
        }    
    }   
}

【讨论】:

    【解决方案2】:

    将关注点分离 (Soc) 和单一职责原则 (SRP) 应用到您的示例中,您需要分解您的类,以便它们不负责太多事情。

    将您的用户(模型)类分解为自己的类

    public class User {
        public int Id;
        public string FirstName;
    } 
    

    将数据访问提取到它自己的类中。

    public class UsersContext {
        string connectionstring = ConfigurationManager.ConnectionStrings["MySqlConnectionString"].ConnectionString.ToString();
    
        public User GetUserById(int UserId) {
            using (var connection = new MySqlConnection(connectionstring)) {
                using (var command = new MySqlCommand()) {
                    command.CommandType = CommandType.Text;
                    command.CommandText = "Select * from User where id='@UserId'";
                    command.Connection = connection;
    
                    var parameter = command.CreateParameter();
                    parameter.ParameterName = "@UserId";
                    parameter.Value = UserId;
    
                    command.Parameters.Add(parameter);
    
                    connection.Open();
                    using (var reader = command.ExecuteReader()) {
                        var user = new User();
                        while (reader.Read()) {
                            user.FirstName = (Convert.IsDBNull(reader["FirstName"]) ? "" : Convert.ToString(reader["FirstName"]));
                        }
                        return user;
                    }
                }
            }
        }
    }
    

    然后让您的 ApiController 专注于处理请求

    public class WebAPIDemoController : ApiController {
    
        [ActionName("GetUser")]
        [HttpGet]
        [Route("api/WebAPIDemo/GetUserById")]
        public IHttpActionResult GetUserById(int id) {
            var context = new UsersContext();
    
            var user = context.GetUserById(id);
    
            return Ok(user);
        }
    }
    

    为了允许下面的请求

    http://localhost:53869/api/WebAPIDemo/GetUserById?id=96
    

    要被路由引擎匹配,你需要确保参数匹配。在您的示例中,您使用查询字符串 ?id=96 调用,但在您的操作中,您有

    GetUserById(int UserId) { ... }
    

    要么将查询字符串更新为?UserId=96,要么将操作参数更改为

    GetUserById(int id) { ... } 
    

    ApiController 中。它们需要匹配,以便在发出请求时路由匹配它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-31
      • 2013-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-20
      • 1970-01-01
      相关资源
      最近更新 更多