一、webservice 部署只能部署IIS上,
比较简单,就不做说明了
安全验证:
- Form
- window身份
- 加个参数,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("custheader")]
public bool UserLoad()
{
if(custheader.Validate())
{
if (header.Name == "admin" && header.Pwd == "123")
{
return true;
}
else
{
return false;
}
}else {
throw new SoapException("身份验证失败",SoapHeaderException.ServerFault.Code)
}
}
要调用这个web Service中的UserLoad 方法,需要传递 CustomSoapHeader 对象参数
二、 WCF 部署 1
》》》》 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 部署方法一样