ASP.NET Web API的入门及常见问题处理

1、创建API

环境说明:
IDE:VS2019社区版;
操作系统:Win 10 专业版

通过VS可方便的创建WebAPI。创建后,会默认创建ValuesController。新建一个API的Controller,并对里面的方法进行了细微修改。具体代码如下:

    public class MyAPIController : ApiController
    {
        // GET: api/MyAPI
        public List<Student> Get()
        {
            List<Student> resultList = new List<Student>();
            Student s1= new Student() { sid = "01", sname = "张三" };
            Student s2 = new Student() { sid = "02", sname = "李四" };
            resultList.Add(s1);
            resultList.Add(s2);

            return resultList;
        }

        // GET: api/MyAPI/5
        public string Get(int id)
        {
            return "当前传入的ID值为:"+id;
        }

        // POST: api/MyAPI
        [HttpPost]
        public Student Post([FromBody] Student Student)
        {
            return Student;
        }

        // PUT: api/MyAPI/5
        [HttpPost]
        public string Put([FromBody]string value)
        {
            return "您传入的值为:"+value;
        }

        // DELETE: api/MyAPI/5
        public void Delete(int id)
        {
        }
    }

2、访问API

将代码编译后部署到IIS上,就可以在本地进行访问了。
需要说明一点,在App_Start的WebApiConfig.cs文件中,一开始生成的配置文件内容如下:

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

以上的配置没有关联action,所以即使你的APIController中定义了多个,你能访问的只能是一个(通过浏览器方式)。若通过代码访问(C#发起http请求),则会报如下的错误:

{“Message”:“出现错误。”,“ExceptionMessage”:"找到了与该请求匹配的多个操作:

因此,需要将action添加待配置文件中。即配置文件如下:

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

2.1 通过Get访问

2.1.1 通过浏览器访问

可直接访问链接

http://localhost/Tsinghua.His.DrugInfoAPI/api/MyAPI/Get

得到接口的内容

2.1.2 通过C#发起Http请求(get)

C#发起的Http请求方法如下:

        static string getResponseByHttpGet(string Url, string postDataStr)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr);
            request.Method = "GET";
            request.ContentType = "text/html;charset=UTF-8";
 
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            string retString = myStreamReader.ReadToEnd();
            myStreamReader.Close();
            myResponseStream.Close();
 
            return retString;
        }

通过调用相关方法,获取对应结果

        static void Main(string[] args)
        {
            string myurl = @"http://localhost/Tsinghua.His.DrugInfoAPI/api/MyAPI/Get";
            string postData = "id=12";

            string myResponse = getResponseByHttpGet(myurl, postData);

            Console.WriteLine(myResponse);
            Console.ReadLine();
        }

运行后,结果如下
在这里插入图片描述

2.2 通过Post访问

1、方法添加HttpPost属性

 public class MyAPIController : ApiController
    {
    	//只对Post方法进行了修改
        [HttpPost]
        public Student Post([FromBody] Student Student)
        {
            return Student;
        }
    }
	
	//新添加了一个类,用于传输数据绑定
    public class Student
    {
        public string sid { get; set; }
        public string sname { get; set; }
    }

2、C#发起Post请求的方法

        //通过键值对方式发送数据
        static string getResponseByHttpPostByKeyValue(string url, string postData)
        {
            //定义request并设置request的路径
            WebRequest request = WebRequest.Create(url);

            //定义请求的方式
            request.Method = "POST";

            //设置参数的编码格式,解决中文乱码
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);

            //设置request的MIME类型及内容长度
            request.ContentType = "application/x-www-form-urlencoded"; //配合传入参数,将request的content-type设为form
            request.ContentLength = byteArray.Length;

            //打开request字符流
            Stream dataStream = request.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();

            HttpWebResponse response;
            try
            {
                //定义response为前面的request响应
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException ex)
            {
                //用于获取明细的异常信息
                response = (HttpWebResponse)ex.Response;
            }


            //获取相应的状态代码
            Console.WriteLine(response.StatusDescription);

            //定义response字符流
            dataStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(dataStream);
            string responseFromServer = reader.ReadToEnd();//读取所有

            //关闭资源
            reader.Close();
            dataStream.Close();
            response.Close();
            return responseFromServer;
        }

3、通过控制台发起一个POST方式的HTTP请求。

        static void Main(string[] args)
        {
            //Post请求
            string postURL = @"http://localhost/Tsinghua.His.DrugInfoAPI/api/MyAPI/POST";
            string postData = "sid=12&sname=张三";
            string postResponseStr = getResponseByHttpPostByKeyValue(postURL, postData);

            Console.WriteLine(postResponseStr);
            Console.ReadLine();
        }        

4、运行效果如下
POST

3、其他处理

3.1 FromBody参数说明

3.1.1 POST方式的数据格式

1、POST方式Request请求时需要指定,传递的数据格式,是JSON还是普通的键值对。若为JSON,则C#发起请求的时候,需要指定requestcontent-typeapplication/json; charset=utf-8,并设定编码方式;当为普通键值对时,content-type需要设为application/x-www-form-urlencoded。两种方式的发起请求,也略微不同。
1.1 当为JSON时,C#发起的请求,应为:

            //POST -json格式的请求
            string jsonPostURL = @"http://localhost/Tsinghua.His.DrugInfoAPI/api/MyAPI/POST";
            Student detailData = new Student() { sid = "001", sname = "张三" }; //将数据转为json
            string jsonPostData = JsonConvert.SerializeObject(detailData);
            string jsonPostResponseStr = getResponseByHttpPostByJson(jsonPostURL, jsonPostData);

            Console.WriteLine(jsonPostResponseStr);
            Console.ReadLine();

1.2 当为普通键值对

            string postURL = @"http://localhost/Tsinghua.His.DrugInfoAPI/api/MyAPI/POST";
            string postData = "sid=12&sname=张三";
            string postResponseStr = getResponseByHttpPostByKeyValue(postURL, postData);

            Console.WriteLine(postResponseStr);
            Console.ReadLine();

3.1.2 FromBody参数

webapi中参数中数据的来源有两种:FromBody和FromUri。在实际的使用中,常常遇到,在使用FromBody,且参数为单一的string时,无法获取传入数据。主要原因是数据格式不准确。

3.1.2.1 单一参数、json格式时

参数应这样调用:

            string jsonPostURL = @"http://localhost/Tsinghua.His.DrugInfoAPI/api/MyAPI/put";
            string jsonPostData = "'hello'"; //要加上单引号
            string jsonPostResponseStr = getResponseByHttpPostByJson(jsonPostURL, jsonPostData);

            Console.WriteLine(jsonPostResponseStr);
            Console.ReadLine();

这个问题,实际上是如何将一个string表示为json对象。

3.1.2.2 单一参数、key-value格式时

参数的调用方式如下。

            string postURL = @"http://localhost/Tsinghua.His.DrugInfoAPI/api/MyAPI/put";
            string postData = "=hello"; //参数要这样写
            string postResponseStr = getResponseByHttpPostByKeyValue(postURL, postData);

            Console.WriteLine(postResponseStr);
            Console.ReadLine();

3.2 返回格式为json

1、有时我们想提供的接口,其返回结果都是json。可以将webapi格式器中xml删除即可实现。即在APP_Start中的WebApiConfig.cs中加添如下的代码即可:

            //清除所有的格式器,然后只添加json格式器
            config.Formatters.Clear();
            config.Formatters.Add(new JsonMediaTypeFormatter());

两者的返回如图所示
在这里插入图片描述json返回
在这里插入图片描述xml格式返回

2、说明
上面的方案好处是简单、省事,缺点是底层的内容协商仍然在使用,为了能够彻底自定义,可以实现IContentNegotiator接口,并在config中进行替换。
自定义实现如下:

public class JsonContentNegotiator : IContentNegotiator
{
    private readonly JsonMediaTypeFormatter _jsonFormatter;

    public JsonContentNegotiator(JsonMediaTypeFormatter formatter) 
    {
        _jsonFormatter = formatter;    
    }

    public ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters)
    {
        var result = new ContentNegotiationResult(_jsonFormatter, new MediaTypeHeaderValue("application/json"));
        return result;
    }
}

在Webapiconfig.cs文件中进行替换

var jsonFormatter = new JsonMediaTypeFormatter();
config.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator(jsonFormatter));

这样,也可以实现返回结果为json。

3.3 POST参数数据

后台接收数据时,可以直接使用Newtonsoft.Json中的JObject,这样就不用写个参数对照类。

//输入用户名和密码,判断数据是否可行
[HttpPost]
public string checkUserInfo(JObject jsonObj)
{
    ResultModel resultModel = new ResultModel();

    try
    {
        bool checkFlag = LoginService.checkLoginfo(jsonObj["username"].ToString(), jsonObj["password"].ToString());

        if (checkFlag)
        {
            resultModel.MsgCode = "ok";
            resultModel.Msg = "验证成功!";
        }
        else
        {
            resultModel.MsgCode = "fail";
            resultModel.Msg = "验证失败!";
        }
    }
    catch (Exception e)
    {

        resultModel.MsgCode = "error";
        resultModel.Msg = "发生异常!信息如下:"+e.Message;
    }


    return JsonConvert.SerializeObject(resultModel); ;
}

这篇文章不错,后台接收POST数据的文章

4、代码下载

提取码:NHZL

1、WebAPI代码。WebApi
2、C#发起请求的Console解决方案代码。Console代码

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值