利用WCF搭建RESTful--纯代码启动

最近学习了这几年忽略了的当前几乎所有的开发技术,有深有浅,而服务层最有兴趣的是RESTfull,看的是java的书。因为不熟悉JSP,于是找了本书细细研读了一次。

dotnet的实现也相对简单,网上也很容易找到WCF实现RESTful的例子。于是我想将其作为开源HIS的服务端的基础服务。因为HIS业务的繁多,需要POST很多的表,如果每个表都需要调整服务的接口定义,这工作量就大了,所以我想,接口是否能动态生成方法名称并动态加载WCF?

第一步,就是不能使用配置文件,纯代码启动WCF。
接口和服务都是动态生成的,没有一个编译好的现成的类可以使用,所以利用配置文件启动WCF是不适用的,于是网上找,还好微软件写得非常详细,以下是页面地址
https://msdn.microsoft.com/zh-cn/magazine/dd315413.aspx

第二步,就是动态生成接口类与服务实现类。
因为逻辑简单,所以这部分也很简单。过程就是利用模板文件生成不同表的接口与服务实现类

 [ServiceContract]
 public interface I{InfoClass}Service
 {
     [OperationContract]
     [WebInvoke(
         Method = ""GET"",
         RequestFormat = WebMessageFormat.Json,
         ResponseFormat = WebMessageFormat.Json,
         UriTemplate = ""{InfoClass}/{__infoId}""
         )]
     {InfoClass} Get{InfoClass}(string __infoId);
....

利用上面的模板文本,替换{InfoClass},程序就得到了希望的类的源代码文本,再将该文本在运行时编译成类

string classCode = codeTemp.Replace("{InfoClass}", infoClass);
//设置编译参数。   
CompilerParameters cp = new CompilerParameters();
cp.GenerateExecutable = false;
cp.GenerateInMemory = true;
cp.ReferencedAssemblies.Add("System.dll");
cp.ReferencedAssemblies.Add("System.Data.dll");
cp.ReferencedAssemblies.Add("System.ServiceModel.dll");
cp.ReferencedAssemblies.Add("System.ServiceModel.Web.dll");       
cp.ReferencedAssemblies.Add("DyncWcf.App.exe");//infoClass所在的程序集
//编译代码。   
CompilerResults result = provider.CompileAssemblyFromSource(cp, classCode);
if (result.Errors.Count > 0)
{
    for (int i = 0; i < result.Errors.Count; i++)
        Console.WriteLine(result.Errors[i]);
    Console.WriteLine("error");
    return null;
}

//获取编译后的程序集。   
Assembly assembly = result.CompiledAssembly;

从assembly中取出接口与实现,就可以动态加载wcf了

Assembly asm = AssemblyHelper.BuildAssembly("CmdInfo");
Type[] types = asm.GetTypes();
Type tpInterface = null;
Type tpService = null;
if(types[0].IsInterface){
    tpInterface = types[0];
    tpService = types[1];
}else{
    tpInterface = types[1];
    tpService = types[0];
}
try{
    string baseUri = "http://localhost:8000/DynWcf";
    ServiceHost sh = new ServiceHost(tpService, new Uri(baseUri));
    //wsdl说明页
    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
    smb.HttpGetEnabled = true;
    sh.Description.Behaviors.Add(smb);
    //
    ServiceEndpoint se = sh.AddServiceEndpoint(
        tpInterface,
        new WebHttpBinding(),
        baseUri);
    se.Behaviors.Add(new WebHttpBehavior());

      //利用头增加用户身份认证,这里简单的是Authorization="fangxing/123"
      sh.Authorization.ServiceAuthorizationManager = new MyServiceAuthorizationManager();

    sh.Open();
    Console.WriteLine("The service is ready.");    
}
catch (Exception ce){
    Console.WriteLine("An exception occurred: {0}", ce.Message);
}

 从这找到简单的权限认证的处理办法
https://www.cnblogs.com/wolf-sun/p/4572591.html
抄其中了一个类的代码如下:

public class MyServiceAuthorizationManager : ServiceAuthorizationManager
{
    protected override bool CheckAccessCore(OperationContext operationContext)
    {
        var ctx = WebOperationContext.Current;
        var auth = ctx.IncomingRequest.Headers[HttpRequestHeader.Authorization];
        if (string.IsNullOrEmpty(auth) || auth != "fangxing/123")
        {
Console.WriteLine("无权访问,Url={0}", operationContext.RequestContext.RequestMessage.Properties["Via"]); ctx.OutgoingResponse.StatusCode
= HttpStatusCode.MethodNotAllowed; return false; } return true; } }

这是我使用postman测试的界面

认证部分,还花了两天的时候翻了两本WCF的书。唉...人笨没办法。我的代码放在CSDN,目的是存点积分:)。当然其实几乎全部代码已帖在上面了。

 

源代码下载地址
https://download.csdn.net/download/kevin2y/10779906




原文地址:https://www.cnblogs.com/kevin-Y/p/9909637.html