.NET WebService \ WCF \ WebAPI 部署总结 以及 window 服务 调试,webservice 的安全验证

Ares-Wang 2024-06-21 13:03:06 阅读 54

一、webservice 部署只能部署IIS上,

比较简单,就不做说明了

安全验证:

Formwindow身份加个参数,token 定时更新可以Soapheader

在这里插入图片描述

》》》soapheader验证

首先要新建一个类

且这个类必须继承SoapHeader类

且这个类型必须有一个无参的构造函数

public class CustomSoapHeader:System.Web.Services.Protocols.SoapHeader { public string UserName{ get; set; } public string PassWord{ get; set; } // 必须有一个无参的构造函数 public CustomSoapHeader() { } public CustomSoapHeader( string userName,string passWord) { this.UserName=userName; this.PassWord=passWord; } public bool Validate() { // 要从数据库取数 判断的 if(this.UserName = xxx && this.PassWord == xxxx) return true; else { } } }

然后再 webService中

public CustomSoapHeader custheader; //在需要的方法上添加SoapHeader 特性 [WebMethod] // 定义SoapHeader传递的方向 //SoapHeaderDirection.In;只发送SoapHeader到服务端,该值是默认值 //SoapHeaderDirection.Out;只发送SoapHeader到客户端 //SoapHeaderDirection.InOut;发送SoapHeader到服务端和客户端 //SoapHeaderDirection.Fault;服务端方法异常的话,会发送异常信息到客户端 [SoapHeader("custheader"),Direction = SoapHeaderDirection.InOut) public bool UserLoad() { if(custheader.Validate()) { if (custheader.Name == "admin" && custheader.Pwd == "123") { return true; } else { return false; } }else { throw new SoapException("身份验证失败",SoapHeaderException.ServerFault.Code) } }

在上面代码中需要注意的是,Web Servies中的Web方法需要抛出SoapExcetion异常才能被客户端捕获到,如果在Debug模式下调试运行的话,还需要在异常设置里把这个异常勾选掉,即编译器不对该异常进行捕获。

要调用这个web Service中的UserLoad 方法,需要传递 CustomSoapHeader 对象参数,客户端使用服务端的UserLoad方法,需要传递CustomSoapHeader

//客户端 WebServiceClient client = new WebServiceClient ();//web引用 CustomSoapHeader Header = new CustomSoapHeader ();//web引用创建soap头对象 //设置soap头变量 Header.UserName = "zen"; Header.PassWord = "123456"; client.custheader= Header; //调用web 方法 Response.Write(client.UserLoad());

》》》

添加 token 校验安全

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

二、 WCF 部署 1

在这里插入图片描述

<system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="metadataBehavior"> <serviceMetadata httpGetEnabled="true"/> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="metadataBehavior" name ="Services.HelloWorldService"> <endpoint binding="wsHttpBinding" contract="Contract.IHelloWorld"/> </service> </services> </system.serviceModel>

wcf 重载

》》每个Operation由一个operation XML Element表示,而每个Operation还应该具有一个能够唯一表示该Operation的ID,这个ID则是通过name属性来定义。Operation元素的Name属性通常使用方法名来定义,所以,如果WCF服务契约中,包含两个相同的操作方法名时,此时就违背了WSDL的规定,这也是WCF不可以使用操作重载的原因。

在这里插入图片描述

》》》 d

namespace xxx{ [ServiceContract] public interface IHelloWorld { [OperationContract(Name = "GetHelloWorldWithoutParam")] string GetHelloWorld(); [OperationContract(Name = "GetHelloWorldWithParam")] string GetHelloWorld(string name); }}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

》》》》 wcf 配置信息

<?xml version="1.0" encoding="utf-8"?> <configuration> <system.serviceModel> <!--配置服务和终结点开始--> <services> <service> <endpoint></endpoint> </service> </services> <!--配置服务和终结点结束--> <!--配置绑定开始--> <bindings> <netTcpBinding> <binding> </binding> </netTcpBinding> </bindings> <!--配置绑定结束--> <!--配置行为开始--> <behaviors> <serviceBehaviors> <behavior> </behavior> </serviceBehaviors> </behaviors> <!--配置行为结束--> </system.serviceModel> </configuration>

在这里插入图片描述

<system.serviceModel> <!--服务--> <services> <!--name:名称空间.类型名--> <!--behaviorConfiguration:behavior的名称,请看behavior配置节的名称--> <service name="WCFLibrary.User" behaviorConfiguration="MyBehavior"> <host> <baseAddresses> <!-- 每种传输协议的baseAddress,用于跟使用同样传输协议Endpoint定义的相对地址组成完整的地址, 每种传输协议只能定义一个baseAddress。HTTP的baseAddress同时是service对外发布服务说明页面的URL --> <add baseAddress="http://localhost:8732/Design_Time_Addresses/WCFLibrary/Service/"/> </baseAddresses> </host> <!-- 除非完全限定,否则地址将与上面提供的基址相关,每个服务可以有多个Endpoint --> <!-- Address:指定这个Endpoint对外的URI,这个URI可以是个绝对地址,也可以是个相对于baseAddress的 相对地址。如果此属性为空,则这个Endpoint的地址就是baseAddress--> <!--bindingConfiguration:binding的名称,请看binding配置节的名称--> <endpoint address="" binding="wsHttpBinding" contract="WCFLibrary.IUser" bindingConfiguration="myHttpBinding"> <identity> <dns value="localhost"/> </identity> </endpoint> <!-- 此终结点不使用安全绑定,应在部署前确保其安全或将其删除--> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <!--绑定--> <bindings> <wsHttpBinding> <binding name="myHttpBinding"> <security mode="None"> <message clientCredentialType="Windows" /> </security> </binding> </wsHttpBinding> </bindings> <!--行为--> <behaviors> <serviceBehaviors> <behavior name="MyBehavior"> <!-- httpGetEnabled - bool类型的值,表示是否允许通过HTTP的get方法获取sevice的WSDL元数据 --> <serviceMetadata httpGetEnabled="True"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>

using System.ServiceModel; //服务契约

using System.Runtime.Serialization; //数据契约

》》》 服务契约

[ServiceContract] public interface ISayHi { [OperationContract] string ToSayHi(); /// <summary> /// 自我介绍 /// </summary> /// <param name="person">个人信息</param> /// <returns>返回个人介绍</returns> [OperationContract] string Introduce(Person person); }

》》》》 数据契约

[DataContract] public class Person { [DataMember(Name="ShortName")] //定义别名 public string Name { get; set; } [DataMember] public int Age { get; set; } [DataMember] public string Country { get; set; } public string Introduce() { return string.Format("Hello,my name is {0}.I am {1} years old.I am from {2}.", Name, Age, Country); } }

注意DataMember属性,可以控制字段的可见性。默认是都可见,如果DataMember属性在类中出现,则没有添加该属性的字段不可见。

部署到IIS 跟部署 webservice 部署方法一样的

wcf 部署2

部署到控制台 要以管理员运行vs,或者 管理员运行 控制台的exe

在控制器项目中

创建IUserInfoService 接口

》》》Abort( ) 方法不会抛出异常, 而 Close( )方法则可能抛出 TimeoutException 和 CommunicationException。

在这里插入图片描述

using System;using System.Collections.Generic;using System.Linq;using System.ServiceModel;using System.Text;using System.Threading.Tasks;namespace ConsoleApp1{ [ServiceContract] public interface IUserInfoService { [OperationContract] int Add(int a, int b); }}

在这里插入图片描述

实现接口

在这里插入图片描述

在app.config中增加

在这里插入图片描述

<system.serviceModel> <services> <service name="ConsoleApp1.UserInfoService" behaviorConfiguration="behaviorConfiguration"> <!--服务的对象--> <host> <baseAddresses> <add baseAddress="http://localhost:8000/"/> <!--服务的IP和端口号--> </baseAddresses> </host> <endpoint address="" binding="basicHttpBinding" contract="ConsoleApp1.IUserInfoService"></endpoint> <!--contract:服务契约--> </service> </services> <behaviors> <serviceBehaviors> <behavior name="behaviorConfiguration"> <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点 --> <serviceMetadata httpGetEnabled="true"/> <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 --> <serviceDebug includeExceptionDetailInFaults="true"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>

《《《启动服务

在这里插入图片描述

在这里插入图片描述

》》》验证是否有效

在这里插入图片描述

》》》如果不放在配置文件中

在这里插入图片描述

》》》

using (ServiceHost host = new ServiceHost(typeof(UserInfoService))) { 向宿主中添加终结点 host.AddServiceEndpoint(typeof(IUserInfoService), new WSHttpBinding(), "http://localhost:8686/userinfoservice"); if (Host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null) { ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(); behavior.HttpGetEnabled = true; behavior.HttpGetUrl = new Uri("http://localhost:8686/userinfoservice/metadata"); host.Description.Behaviors.Add(behavior); host.Opened +=delegate { Console.WriteLine("服务已启动"); }; host.Open(); Console.ReadKey(); host.Close(); } }

或者

//创建宿主的基地址 Uri baseAddress = new Uri("http://localhost:8080/User"); //创建宿主 using (ServiceHost host = new ServiceHost(typeof(User), baseAddress)) { //向宿主中添加终结点 host.AddServiceEndpoint(typeof(IUser), new WSHttpBinding(), ""); //将HttpGetEnabled属性设置为true ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); smb.HttpGetEnabled = true; //将行为添加到Behaviors中 host.Description.Behaviors.Add(smb); //打开宿主 host.Open(); Console.WriteLine("WCF中的HTTP监听已启动...."); Console.ReadLine(); host.Close(); }

》》》 校验是否成功

在这里插入图片描述

在这里插入图片描述

部署到winform

在这里插入图片描述

private void button1_Click(object sender, EventArgs e) { ServiceHost Host = new ServiceHost(typeof(WCF.Student)); //绑定 System.ServiceModel.Channels.Binding httpBinding = new BasicHttpBinding(); //终结点 Host.AddServiceEndpoint(typeof(IWCF.IStudent), httpBinding, "http://localhost:8002/"); if (Host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null) { //行为 ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(); behavior.HttpGetEnabled = true; //元数据地址 behavior.HttpGetUrl = new Uri("http://localhost:8002"); Host.Description.Behaviors.Add(behavior); //启动 Host.Open(); } }

》》》验证

在这里插入图片描述

app.config 配置

<service name="WCF.Student" behaviorConfiguration="behaviorConfiguration"> <!--//服务的对象--> <host> <baseAddresses> <add baseAddress="http://localhost:5678"/> <!--// 服务的IP和端口号--> </baseAddresses> </host> <endpoint address="" binding="wsHttpBinding" contract="IWCF.IStudent"></endpoint> <!--//contract:服务契约--> </service> </services> <behaviors> <serviceBehaviors> <behavior name="behaviorConfiguration"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="False"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>

在这里插入图片描述

》》》》验证

在这里插入图片描述

WCF 宿主 服务

在这里插入图片描述

在这里插入图片描述

》》》 app.config 或者写作code 都行

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

LocalService:充当本地计算机上非特权用户的帐户,该帐户将匿名凭据提供给所有远程服务器。

NetworkService:提供广泛的本地特权的帐户,该帐户将计算机的凭据提供给所有远程服务器。

LocalSystem:服务控制管理员使用的帐户,它具有本地计算机上的许多权限并作为网络上的计算机。

User:由网络上特定的用户定义的帐户。如果为 ServiceProcessInstaller.Account 成员指定 User,则会使系统在安装服务时提示输入有效的用户名和密码,除非您为 ServiceProcessInstaller 实例的 Username 和 Password 这两个属性设置值。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

删除服务

sc delete 服务名称

在这里插入图片描述

在这里插入图片描述

window 服务调试

正常是无法调试的,可以在window服务中做调整

如下

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

<connectionStrings> <!--服务开启时间--> <add name="ServiceStart" connectionString="9:00"/> <!--服务执行间隔(秒)--> <add name="ServiceInterval" connectionString="60"/> <!--服务停止时间--> <add name="ServiceEnd" connectionString="17:00"/> <!--服务是否开启(1开启、0关闭)--> <add name="ServiceIsOn" connectionString="0"/> </connectionStrings>

在这里插入图片描述

public partial class Service1 : ServiceBase { //服务配置项 private static string ServiceStart = ConfigurationManager.ConnectionStrings["ServiceStart"].ConnectionString; private static int ServiceInterval = Convert.ToInt32(ConfigurationManager.ConnectionStrings["ServiceInterval"].ConnectionString); private static string ServiceEnd = ConfigurationManager.ConnectionStrings["ServiceEnd"].ConnectionString; private static string ServiceIsOn = ConfigurationManager.ConnectionStrings["ServiceIsOn"].ConnectionString; //服务定时器 private System.Timers.Timer timer = new System.Timers.Timer(); public Service1() { InitializeComponent(); } /// <summary> /// 开启服务 /// </summary> /// <param name="args"></param> protected override void OnStart(string[] args) { if (ServiceIsOn == "1") { timer.Enabled = true; timer.Interval = ServiceInterval * 1000;//执行间隔时间,单位为毫秒; 这里实际间隔为1秒钟 timer.Start(); timer.Elapsed += new System.Timers.ElapsedEventHandler(Procedure_Timer); Procedure_Timer(null, null); } } /// <summary> /// 定时器执行 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Procedure_Timer(object sender, System.Timers.ElapsedEventArgs e) { timer.Enabled = false; TestClass service = new TestClass(); DateTime newDate = DateTime.Now; //获取当前时间 int intHour = newDate.Hour; int intMinute = newDate.Minute; //开始时间 string[] startStamp = ServiceStart.Split(':'); int startHour = Convert.ToInt32(startStamp[0]); int startMinute = Convert.ToInt32(startStamp[1]); //结束时间 string[] endStamp = ServiceEnd.Split(':'); int endHour = Convert.ToInt32(endStamp[0]); int endMinute = Convert.ToInt32(endStamp[1]); int newTime = (intHour * 100) + intMinute; int startTime = (startHour * 100) + startMinute; int endTime = (endHour * 100) + endMinute; // 每天定点在一个时间段内执行 if (newTime >= startTime && newTime <= endTime) { //执行业务代码 // } timer.Enabled = true; } /// <summary> /// 关闭服务 /// </summary> protected override void OnStop() { timer.Stop(); } }

》》》wcf 宿主到 服务中 调试方法

在这里插入图片描述

window 服务 卸载

》》》1 在cmd中 录入 sc delete 服务名称 注意注意 是服务名称 不是显示名称

这种方法 不需要 停车服务,可以直接干掉

》》》2、 代码实现

卸载前,一定要停止掉Windows服务,否则需要重启或注销电脑。代码无法停止服务时,使用services.msc来停止。

获取系统所有window 服务

ServiceController[] services = ServiceController.GetServices();

》》》》“Service1.cs”的代码,增加服务启动日志和停止日志。

using CommonUtils;using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Diagnostics;using System.Linq;using System.ServiceProcess;using System.Text;namespace ADemoWinSvc{ public partial class Service1 : ServiceBase { public Service1() { InitializeComponent(); } protected override void OnStart(string[] args) { GLog.WLog("服务已启动"); } protected override void OnStop() { GLog.WLog("服务已停止"); } }}

》》》》 工具类

using System;using System.IO;namespace CommonUtils{ public static class GLog { static object _lockObj = new object(); public static void WLog(string content) { lock (_lockObj) { string curPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName); string logDir = "Logs"; string logDirFullName = Path.Combine(curPath, logDir); try { if (!Directory.Exists(logDirFullName)) Directory.CreateDirectory(logDirFullName); } catch { return; } string fileName = "Logs" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt"; string logFullName = Path.Combine(logDirFullName, fileName); try { using (FileStream fs = new FileStream(logFullName, FileMode.Append, FileAccess.Write)) using (StreamWriter sw = new StreamWriter(fs)) sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " " + content); } catch { return; } } } }}

========= 上面代码都是 服务中的

下面代码 是winForm程序中的==

在这里插入图片描述

using CommonUtils;using System;using System.Collections;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.IO;using System.Linq;using System.Text;using System.Windows.Forms;namespace Windows服务操作{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } /// <summary> /// windows服务名 /// </summary> static string _winSvcName = "ADemoWinSvc"; /// <summary> /// windows服务对应的exe 名 /// </summary> static string _winSvcExeName = "ADemoWinSvc.exe"; private void btnSetup_Click(object sender, EventArgs e) { try { //是否存在服务 if (ServiceUtil.ServiceIsExisted(_winSvcName)) { //已存在,检查是否启动 if (ServiceUtil.IsRun(_winSvcName)) { //服务是已启动状态 lblMsg.Text = "[001]服务是已启动状态"; } else { //未启动,则启动 ServiceUtil.StarService(_winSvcName); lblMsg.Text = "[002]服务是已启动状态"; } } else { //不存在,则安装 IDictionary mySavedState = new Hashtable(); string curPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName); string apppath = Path.Combine(curPath, _winSvcExeName); ServiceUtil.InstallService(mySavedState, apppath); lblMsg.Text = "[003]服务是已启动状态"; //安装后并不会自动启动。需要启动这个服务 ServiceUtil.StarService(_winSvcName); lblMsg.Text = "[004]服务是已启动状态"; } } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void btnUninstall_Click(object sender, EventArgs e) { //** 卸载服务最重要的是先停止,否则电脑需要重启或注销 ** try { //是否存在服务 if (!ServiceUtil.ServiceIsExisted(_winSvcName)) { MessageBox.Show("服务不存在,不需要卸载"); return; } //如果服务正在运行,停止它 if (ServiceUtil.IsRun(_winSvcName)) { ServiceUtil.StopService(_winSvcName); } //再检查一次是否在运行 if (ServiceUtil.IsRun(_winSvcName)) { MessageBox.Show("服务无法停止,请手动停止这个服务"); return; } //卸载 ServiceUtil.UnInstallServiceByName(_winSvcName); lblMsg.Text = "[005]服务已卸载"; } catch (Exception ex) { MessageBox.Show(ex.Message); } } }}

》》》》》

AssemblyInstaller 帮助文件

https://learn.microsoft.com/zh-cn/dotnet/api/system.configuration.install.assemblyinstaller?view=netframework-4.8.1

》》》》 工具类

using System;using System.Collections;using System.Collections.Generic;using System.Configuration.Install;using System.Diagnostics;using System.Linq;using System.ServiceProcess;using System.Text;namespace CommonUtils{ /// <summary> /// windows服务操作工具类 /// </summary> public static class ServiceUtil { /// <summary> /// 服务是否正在运行 /// </summary> /// <param name="name"></param> /// <returns></returns> public static bool IsRun(string name) { bool IsRun = false; try { if (!ServiceIsExisted(name)) return false; var sc = new ServiceController(name); if (sc.Status == ServiceControllerStatus.StartPending || sc.Status == ServiceControllerStatus.Running) { IsRun = true; } sc.Close(); } catch { IsRun = false; } return IsRun; } /// <summary> /// 启动服务 /// </summary> /// <param name="name"></param> /// <returns></returns> public static bool StarService(string name) { try { var sc = new ServiceController(name); if (sc.Status == ServiceControllerStatus.Stopped || sc.Status == ServiceControllerStatus.StopPending) { sc.Start(); sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 10)); } else { } sc.Close(); return true; } catch (Exception ex) { throw ex; } } /// <summary> /// 停止服务(有可能超时) /// </summary> /// <param name="name"></param> /// <returns></returns> public static bool StopService(string name) { try { var sc = new ServiceController(name); if (sc.Status == ServiceControllerStatus.Running || sc.Status == ServiceControllerStatus.StartPending) { sc.Stop(); //停止服务超时时间:56秒。 sc.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 56)); } else { } sc.Close(); return true; } catch (Exception ex) { throw ex; } } /// <summary> /// 是否存在 /// </summary> /// <param name="serviceName"></param> /// <returns></returns> public static bool ServiceIsExisted(string serviceName) { ServiceController[] services = ServiceController.GetServices(); foreach (ServiceController s in services) if (s.ServiceName.ToLower() == serviceName.ToLower()) return true; return false; } /// <summary> /// 安装 /// </summary> /// <param name="stateSaver"></param> /// <param name="filepath"></param> public static void InstallService(IDictionary stateSaver, string filepath) { try { AssemblyInstaller myAssemblyInstaller = new AssemblyInstaller(); myAssemblyInstaller.UseNewContext = true; myAssemblyInstaller.Path = filepath; myAssemblyInstaller.Install(stateSaver); myAssemblyInstaller.Commit(stateSaver); myAssemblyInstaller.Dispose(); } catch (Exception ex) { throw ex; } } /// <summary> /// 使用路径卸载(有时候不便于用路径来卸载,则使用SC DELETE 名称来卸载) /// </summary> /// <param name="filepath"></param> public static void UnInstallService(string filepath) { try { AssemblyInstaller myAssemblyInstaller = new AssemblyInstaller(); myAssemblyInstaller.UseNewContext = true; myAssemblyInstaller.Path = filepath; myAssemblyInstaller.Uninstall(null); myAssemblyInstaller.Dispose(); } catch (Exception ex) { throw ex; } } /// <summary> /// 使用windows服务名卸载 /// </summary> /// <param name="WinServiceName"></param> public static void UnInstallServiceByName(string WinServiceName) { ProcessStartInfo pStart = new ProcessStartInfo("sc.exe"); Process pRoc = new Process(); pStart.Arguments = " delete " + WinServiceName; pStart.UseShellExecute = false; pStart.CreateNoWindow = false; pRoc.StartInfo = pStart; pRoc.Start(); pRoc.WaitForExit(); } }}

wcf 服务 部署之后,测试

在这里插入图片描述

在这里插入图片描述

》》》或者通过SvcUtil.exe 生成代理类

会生成 两个文件

》xxxx.cs 类

》 xxx.config

将 xxx.config 中的内容copy到 程序目录下 App.config

同时将这个xxx.cs 类添加到 项目中

添加引用 System.Runtime.Serialization、System.ServiceModel ;

这个项目就可以使用wcf的服务

WebAPI 部署

部署 IIS

跟wcf 、webservice 一样。

部署 控制台

安装

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

static void Main(string[] args) { RegisterWebApi("http://localhost:4554"); } private static void RegisterWebApi(string url) { var config = new HttpSelfHostConfiguration(url); config.Routes.MapHttpRoute( "API Default", "api/{controller}/{action}/{id}", new { id = RouteParameter.Optional }); using (HttpSelfHostServer server = new HttpSelfHostServer(config)) { server.OpenAsync().Wait(); Console.WriteLine("Press Enter to quit."); Console.ReadLine(); } }

在这里插入图片描述

webapi 路由 一般没有 action 符合 RESETFUL 风格

在这里插入图片描述

》》》》》 部署到 winForm

安装如下:

在这里插入图片描述

在这里插入图片描述

添加控制器》》》

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

window 服务 也一样的

上面都说 selfhost

下面介绍》》》》 OwinSelfHost

OwinSelfHost

安装

注意注意 注意

是 Microsoft.AspNet.WebApi.oWinSelfHost

在这里插入图片描述

》》》添加Owin启动类

在这里插入图片描述

》》创建好 Owin Startup 如下

// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888 // 有关如何配置应用程序的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=316888 HttpConfiguration config = new HttpConfiguration(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{Controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional }); app.UseWebApi(config);

在这里插入图片描述

》》》》 新建控制器

在这里插入图片描述

》》》在Program中写入如下代码

在这里插入图片描述

static void Main(string[] args) { string baseAddress = "http://localhost:9527/"; using (WebApp.Start(url: baseAddress)) { Console.WriteLine("请开始您的表演"); Console.ReadLine(); } }

》》》 验证

在这里插入图片描述

webapi 部署到 window 服务

首先 新建 window服务程序

在这里插入图片描述

步骤跟上面一样的

至少 服务启动 要 OnStart

在这里插入图片描述

》》》》安装 服务

在这里插入图片描述

在这里插入图片描述

》》》 window Form 部署方法一样

优缺点

Web Services SOAP、UDDI、WSDL

优点:

跨平台:Web Services完全基于XML(可扩展标记语言)、XSD(XMLSchema)等与平台无关的行业标准。

自描述:Web Service使用WSDL进行自我描述,包括服务的方法、参数、类型和返回值等相关信息。

跨防火墙:Web Service使用http协议进行通信,可以穿越防火墙。

缺点:

效率低下,不适合做单应用系统的开发。

安全问题:Web Services没有自身的安全机制,必须借助Http协议或IIS等宿主程序实现信息安全加密。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。