开发环境

开发版本.Net Framework 4.6.1,开发工具VS2019

需要下载的Nuget包

1、Microsoft.Owin(2.1.0)
2、Microsoft.Owin.Cors(2.1.0)
3、Microsoft.Owin.Hosting(2.1.0)
4、Microsoft.Owin.Security.OAuth(2.1.0)
5、Microsoft.Owin.Host.HttpListener(2.1.0)(如果启动项目没有则需要在启动项目下载引用)
6、Microsoft.AspNet.WebApi.Owin(5.2.7)
7、Microsoft.AspNet.WebApi.WebHost(5.2.7)
8、Microsoft.AspNet.Cors(5.0.0)
9、Microsoft.Owin.StaticFiles(2.1.0)(如果托管静态文件需要安装)

配置及使用

1、添加WebApiConfiguration

public class WebApiConfiguration
{
    public static HttpConfiguration HttpConfig { get; private set; }

    public void Configuration(IAppBuilder app)
    {
        //app.UseStaticFiles();
        //注册跨域请求许可
        app.UseCors(CorsOptions.AllowAll);
        //注册中间件
        app.Use<LogMiddleware>();
        app.UseMiddleware();
        #region 配置静态文件托管

        var physicalFileSystem = new PhysicalFileSystem(@".\www"); //静态网站根目录
        var options = new FileServerOptions
        {
            EnableDefaultFiles = true,
            FileSystem = physicalFileSystem
        };
        options.StaticFileOptions.FileSystem = physicalFileSystem;
        options.StaticFileOptions.ServeUnknownFileTypes = true;
        options.DefaultFilesOptions.DefaultFileNames = new[] { "Index.html" }; //默认页面(填写与静态网站根目录的相对路径)

        #endregion

        //var oAuthOptions = new OAuthAuthorizationServerOptions
        //{
        //    Provider = new AuthorizationServerProvider()
        //};
        //app.UseOAuthAuthorizationServer(oAuthOptions);
        app.UseFileServer(options);
        //注册WebApi服务
        var config = Register();
        app.UseWebApi(config);
    }

    public static HttpConfiguration Register()
    {
        HttpConfig = new HttpConfiguration();

        HttpConfig.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new DefaultContractResolver() { IgnoreSerializableAttribute = true };
        HttpConfig.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
        HttpConfig.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("datatype", "json", "application/json"));
        HttpConfig.Formatters.JsonFormatter.SerializerSettings.Converters.Add(
            new Newtonsoft.Json.Converters.IsoDateTimeConverter()
            {
                DateTimeFormat = "yyyy-MM-dd HH:mm:ss"
            }
        );
        HttpConfig.MapHttpAttributeRoutes();
        HttpConfig.Routes.MapHttpRoute("DefaultApi", "{controller}/{id}", new { id = RouteParameter.Optional });

        return HttpConfig;
    }
}

2、添加WebApiServer

public class WebApiServer
{
    private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();

    public const string Started = "STARTED";
    public const string Stopped = "STOPPED";

    private static IDisposable _webApplication;

    public static string State { get; private set; }

    public static bool Run(int port)
    {
        if (State == Started)
        {
            _logger.Info($"WebAPI Running.");
            return true;
        }

        if (port > 0)
        {
            var url = $"http://+:{port}";
            try
            {
                _webApplication = WebApp.Start<WebApiConfiguration>(url);
                _logger.Info($"Run WebAPI,Port:{port}");
            }
            catch (Exception e)
            {
                _logger.Info($"Run WebAPI Failed,Port:{port}, \r\nMessage:{e.Message},\r\nReason:{e.StackTrace}");
                return false;
            }

            State = Started;
            return true;
        }
        else
        {
            return false;
        }
    }

    public static bool Stop()
    {
        if (State == Stopped)
        {
            _logger.Info($"WebAPI Stopped.");
            return true;
        }
        try
        {
            _webApplication?.Dispose();
        }
        catch (Exception e)
        {
            _logger.Info($"Stop WebAPI Failed, \r\nMessage:{e.Message},\r\nReason:{e.StackTrace}");
            return false;
        }
        State = Stopped;
        return true;
    }
}

3、添加ServiceContainer

public class ServiceContainer
{
    private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
    static ServiceContainer()
    {
        Services = new ServiceContainer();
    }

    public ServiceContainer()
    {

    }

    public static ServiceContainer Services { get; private set; }

    /// <summary>
    /// 启动服务
    /// </summary>
    /// <param name="port"></param>
    /// <returns></returns>
    public bool Start(int port)
    {
        var result = false;
        try
        {
            result = WebApiServer.Run(port);
        }
        catch (Exception ex)
        {
            _logger.Error("Start", $"Unhandled main process exception: {ex.Message}");
            _logger.Error("Start", ex.StackTrace);
        }
        return result;
    }

    /// <summary>
    /// 停止服务
    /// </summary>
    /// <returns></returns>
    public bool Stop()
    {
        return WebApiServer.Stop();
    }
}

4、启动/停止网站时调用代码

var ServiceContainer = new ServiceContainer();
// 启动网站
ServiceContainer.Start(9090);
// 停止网站
ServiceContainer.Stop();