WebApi-寄宿方式注意事项

发布时间 2023-07-26 12:01:57作者: 丹心石
所谓的寄宿方式,就是把服务从原来的容器(iis、appache)中提取出来通过宿主程序来控制其启动,这样的好处就是避免了对服务器(容器)的依赖,实现灵活控制,但在实际开发中尤其是新手容易忽略的地方,这里做个简单的示例,记录一下便于以后自查。
  • 首先建立一个公共各类库 Common,用于存放实体类。编写一个实体类 Contact
namespace Common
{
    public class Contact
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string PhoneNo { get; set; }
        public string EmailAddress{get;set;}
        public string Address { get; set; }
    }
}

  • 接着在建立一个类库 SelfHost,用于编写WebApi 控制器(为了让宿主调用,把WebAPI服务放在类库中实现,这和WCF 是一样的)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
using Common;
using System.Threading;
using Newtonsoft.Json;
using System.Web.Http.Cors;

namespace WebApi
{
    [EnableCors(origins:"*",headers:"*",methods:"*")]  //为了解决跨域问题,这里引用的Cors 要保持和宿主中一致,Newtonsoft.JSon 也是如此
    public class ContactsController:ApiController
    {
        static List<Contact> contacts;
        static int counter = 2;
        public ContactsController()
        {
            contacts = new List<Contact> {
                new Contact{ Id="1001",Name="张三",PhoneNo="13663782541",EmailAddress="zhangsan@163.com",Address="河南南阳"},
                new Contact{ Id="1002",Name="李四",PhoneNo="13683782542",EmailAddress="lisi@163.com",Address="河南信阳"}
            };
        }
        [HttpGet]
        public IEnumerable<Contact> Get(string Id = null) {
            return contacts.Where(c => c.Id == Id||string.IsNullOrEmpty(Id));
        }
        [HttpPost]
        public List<Contact> Post(dynamic obj) {
            Interlocked.Increment(ref counter);
            Contact contact = new Contact {
                Id = counter.ToString("D3"),
                Name = obj.Name,
                PhoneNo=obj.PhoneNo,
                EmailAddress=obj.EmailAddress,
                Address=obj.Address

            };
            contacts.Add(contact);
            return contacts;
        }
        [HttpDelete]
        public List<Contact> Delete(string Id) {
            contacts.Remove(contacts.First(c => c.Id == Id));
            return contacts;
        }

    }
}

  • 最后编写宿主程序,这里以控制台程序为例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
using System.Net.Http.Formatting;
using System.Web.Http.SelfHost;
using System.Reflection;
using System.Web.Http.Cors;
namespace SelfHost
{
    class Program
    {
        static void Main(string[] args)
        {
            string url = "http://localhost/selfhost/api/contacts";   // 提供给客户端参考的地址
            Assembly.Load("WebApi,Version=1.0.0.0,Culture=neutral,PublicToken=null");
            HttpSelfHostConfiguration configuration = new   //这里的configuration 和原始WebAPI 的Glob.asxa 中的config 对象是一样的,都是用来为当前的WebApi服务提供配置信息 HttpSelfHostConfiguration("http://localhost/selfhost");  //这里的地址是基地址,即类似原始WebApi中的 localhost:8080
            configuration.Formatters.Remove(configuration.Formatters.XmlFormatter);  //删除默认的xml格式
            configuration.Formatters.Add(new JsonMediaTypeFormatter());   //增加JSON格式 
            configuration.EnableCors(); //启用跨域
            using (HttpSelfHostServer httpServer = new HttpSelfHostServer(configuration)) {
                httpServer.Configuration.Routes.MapHttpRoute(  //设置服务器的路由信息
                    name:"DefaultApi",
                    routeTemplate:"api/{controller}/{id}",
                    defaults: new { id=RouteParameter.Optional}
                    );
                httpServer.OpenAsync().Wait();  //启动服务
                Console.WriteLine("WebApi 服务器已启动...");
                Console.WriteLine($"地址:{url}");
                Console.Read();
            }
        }
    }
}

  • 启动服务
    image

  • 浏览器访问
    image

  • 测试跨域
    HTHML代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="js/jquery-1.10.2.js"></script>
		<script>
		
			function f1(){
				$.ajax({
					type:"get",
					url:"http://localhost:58208/api/home",
					data:{},
					async:true,
					success:function(res){
						$("#txt").append(JSON.stringify(res)+"\n");
						
					},
					error:function(err){
						alert(JSON.stringify(err));
					}
					
				});
				
			}
			
           function f2(){
           	$.ajax({
           		type:"get",
           		url:"http://localhost:58208/api/home",
           		data:{"name":"张三"},
           		async:true,
           		success:function(res){
           			$("#txt").append(JSON.stringify(res)+"\n");
           			
           		},
           		error:function(err){
           			alert(JSON.stringify(err));
           			
           		}
           	});

           }
		function f3() {
		
			$.ajax({
				type:"post",
				url:"http://localhost:58208/api/home",
				contentType:"application/json",
				data:JSON.stringify({"name":"张三","age":12}),
				async:true,
				success:function(res){
					$("#txt").append(JSON.stringify(res)+"\n");
				},
				error:function(err){
					alert(JSON.stringify(err));
					
				}
			});
		
			
		}
		function f4(){
			$.ajax({
				type:"get",
				url:"http://localhost/selfhost/api/contacts",
				async:true,
				success:function(res){
					$("#txt").append(JSON.stringify(res));
					
				},
				error:function(err){
					alert(JSON.stringify(err));
					
				}
			});
			
		}
		</script>
	</head>
	<body>
		<div>
			<button onclick="f1()">测试1-Get无参</button>
			<button onclick="f2()">测试2-Get有参</button>
			<button onclick="f3()">测试3-Post动态参数</button>
			<button onclick="f4()">寄宿服务测试-Get</button>
		</div>
		<div>
			<textarea id="txt" rows="25" cols="38" ></textarea>
		</div>
	</body>
</html>

测试效果:
image