• C#开发BIMFACE系列12 服务端API之文件转换


    在代表模型的源文件上传到BIMFACE后,一般会进行三种API调用操作:

    1. 发起模型转换

    2. 查询转换状态

    3. 如转换成功,获取模型转换后的BIM数据

    在模型成功进行转换后,模型内的BIM信息会在云端进行解析,抽取并结构化入库。这些信息包含:
    • 构件属性信息

    • 构件分类树

    • 楼层

    • 单体

    • 专业

    • 构件材质

    • 模型链接

    • 空间

    • 房间

    • 图纸

    • …​

    在确认模型转换成功后,为了开发者能方便的获取这些BIM信息并集成在自己的应用中,BIMFACE提供了一系列的数据接口,这些接口支持两种验权方式:

    Access token: 代表自身应用的身份,使用应用的appkey, secret,通过调用/oauth2/token接口获取。
    View token:    代表对单个模型的访问权限,使用access token,通过调用/view/token以及相关接口获得。

    发起转换

    请求地址:PUT https://api.bimface.com/translate

    说明:源文件上传成功后,即可发起对该文件的转换。由于转换不能立即完成,BIMFace支持在文件转换完成以后,通过Callback机制通知应用;另外,应用也可以通过接口查询转换状态。

    参数:application/json 格式

    请求 path(示例):https://api.bimface.com/translate

    请求 header(示例):"Authorization: Bearer dc671840-bacc-4dc5-a134-97c1918d664b"

    请求 body(示例):

    {
      "callback" : "https://api.glodon.com/viewing/callback?authCode=iklJk0affae&signature=2ef131395fb6442eb99abd83d45c3201",
      "config" : {
        "string" : "string"
      },
      "priority" : 2,
      "source" : {
        "compressed" : false,
        "fileId" : 1277823232112,
        "rootName" : "rootFileName.rvt"
      }
    } 
    注意:请求体中的 config 可以设置为空。"config":null 或者传入指定的转换参数 "config":{"texture":true} 。

    HTTP响应示例(200):

    {
      "code" : "success",
      "data" : {
        "createTime" : "2017-12-25 17:23:46",
        "databagId" : "9b711803a43b92d871cde346b63e5019",
        "fileId" : 1248789071339712,
        "name" : "bimface_2018.rvt",
        "priority" : 2,
        "reason" : "reason",
        "status" : "success",
        "thumbnail" : [ "https://m.bimface.com/9b711803a43b92d871cde346b63e5019/thumbnail/96.png", "https://m.bimface.com/9b711803a43b92d871cde346b63e5019/thumbnail/256.png" ]
      },
      "message" : ""
    }
     
    请求体内的参数解释
     

    DGW与RVT格式的文件转换的配置参数不同,所以封装了2个对应的C#类:

     1 /// <summary>
     2 ///  发起DWG文件转化的请求数据
     3 /// </summary>
     4 [Serializable]
     5 public class DwgFileTranslateRequest : FileTranslateRequest
     6 {
     7     /// <summary>
     8     ///  Dwg模型转换引擎自定义参数,config参数跟转换引擎相关,不同的转换引擎支持不同的config格式。
     9     /// 例如转换时添加内置材质,则添加参数值{"texture":true},添加外部材质时参考“使用模型外置材质场景”请求报文。
    10     /// 如果不需要设置该参数,则设置为null
    11     /// </summary>
    12     [JsonProperty("config", NullValueHandling = NullValueHandling.Ignore)]
    13     public DwgModelConfig Config { get; set; }
    14 }
     1 /// <summary>
     2 ///  发起Rvt文件转化的请求数据
     3 /// </summary>
     4 [Serializable]
     5 public class RvtFileTranslateRequest : FileTranslateRequest
     6 {
     7     /// <summary>
     8     ///  Rvt模型转换引擎自定义参数,config参数跟转换引擎相关,不同的转换引擎支持不同的config格式。
     9     /// 例如转换时添加内置材质,则添加参数值{"texture":true},添加外部材质时参考“使用模型外置材质场景”请求报文。
    10     /// 如果不需要设置该参数,则设置为null
    11     /// </summary>
    12     [JsonProperty("config", NullValueHandling = NullValueHandling.Ignore)]
    13     public RvtModelConfig Config { get; set; }
    14 }
    1 /// <summary>
    2 ///  其他三维模型文件,包括RVT格式文转化的请求数据
    3 /// </summary>
    4 [Serializable]
    5 public class Other3DModelFileTranslateRequest : RvtFileTranslateRequest
    6 {
    7 }
     1 [Serializable]
     2 public class TranslateSource
     3 {
     4     public TranslateSource()
     5     {
     6         Compressed = false;
     7         RootName = null;
     8     }
     9 
    10     /// <summary>
    11     ///  文件Id,即调用上传文件API返回的fileId
    12     /// </summary>
    13     [JsonProperty("fileId")]
    14     public long FileId { get; set; }
    15 
    16     /// <summary>
    17     ///  是否为压缩文件,默认为false
    18     /// </summary>
    19     [JsonProperty("compressed")]
    20     public bool Compressed { get; set; }
    21 
    22     /// <summary>
    23     ///  如果是压缩文件,必须指定压缩包中哪一个是主文件。(例如:root.rvt)。
    24     /// 如果不是压缩,则设置为 null
    25     /// </summary>
    26     [JsonProperty("rootName", NullValueHandling = NullValueHandling.Ignore)]
    27     public string RootName { get; set; }
    28 }

    共同的基类FileTranslateRequest:

     1 /// <summary>
     2 ///  发起文件转化的请求数据
     3 /// </summary>
     4 [Serializable]
     5 public class FileTranslateRequest
     6 {
     7     public FileTranslateRequest()
     8     {
     9         Priority = 2;
    10         CallBack = "http://www.app.com/receive";
    11     }
    12 
    13     [JsonProperty("source")]
    14     public TranslateSource Source { get; set; }
    15 
    16     /// <summary>
    17     /// 优先级,数字越大,优先级越低。只能是1, 2, 3。默认为2
    18     /// </summary>
    19     [JsonProperty("priority")]
    20     public int Priority { get; set; }
    21 
    22     /// <summary>
    23     ///  Callback地址,待转换完毕以后,BIMFace会回调该地址
    24     /// </summary>
    25     [JsonProperty("callback")]
    26     public string CallBack { get; set; }
    27 }

    不同模型转换支持的自定义参数config:

    (1) rvt模型

    对应封装成的C#实体类:

     1 /// <summary>
     2 ///  rvt 模型配置项
     3 /// </summary>
     4 [Serializable]
     5 public class RvtModelConfig
     6 {
     7     public RvtModelConfig()
     8     {
     9         //设置 null,在序列化的时候忽略该字段,不出现在序列化后的字符串中
    10         Texture = null;
    11         ExportDwg = null;
    12         ExportDrawing = null;
    13         ExportPdf = null;
    14         ViewName = null;
    15         DisplayLevel = null;
    16         ExportDwgInstance = null;
    17         ExportHiddenObjects = null;
    18         ExportSystemType = null;
    19         ExportProperties = null;
    20         Unit = null;
    21         ExportSchedule = null;
    22     }
    23 
    24     /// <summary>
    25     ///  转换时是否添加材质。默认为 false
    26     /// </summary>
    27     [JsonProperty("texture", NullValueHandling = NullValueHandling.Ignore)]
    28     public bool? Texture { get; set; }
    29 
    30     /// <summary>
    31     ///  rvt2md是否导出dwg文件。默认为 false
    32     /// </summary>
    33     [JsonProperty("exportDwg", NullValueHandling = NullValueHandling.Ignore)]
    34     public bool? ExportDwg { get; set; }
    35 
    36     /// <summary>
    37     ///  dwg2md是否导出mdv(矢量化图纸);取值为true时,exportDwg自动设置为true。默认为 false
    38     /// </summary>
    39     [JsonProperty("exportDrawing", NullValueHandling = NullValueHandling.Ignore)]
    40     public bool? ExportDrawing { get; set; }
    41 
    42     /// <summary>
    43     ///  dwg2md是否导出pdf文件。默认为 false
    44     /// </summary>
    45     [JsonProperty("exportPdf", NullValueHandling = NullValueHandling.Ignore)]
    46     public bool? ExportPdf { get; set; }
    47 
    48     /// <summary>
    49     ///  转换使用的3D视图。默认为 {3D}
    50     /// </summary>
    51     [JsonProperty("viewName", NullValueHandling = NullValueHandling.Ignore)]
    52     public string ViewName { get; set; }
    53 
    54     /// <summary>
    55     ///  设置转换的精细度,fine(精细),medium(中等),coarse(粗略)。默认为 fine
    56     /// </summary>
    57     [JsonProperty("displaylevel", NullValueHandling = NullValueHandling.Ignore)]
    58     public string DisplayLevel { get; set; }
    59 
    60     /// <summary>
    61     /// 是否导出dwg实例。默认为 false
    62     /// </summary>
    63     [JsonProperty("exportDwgInstance", NullValueHandling = NullValueHandling.Ignore)]
    64     public bool? ExportDwgInstance { get; set; }
    65 
    66     /// <summary>
    67     /// 是否导出三维视图中隐藏的构件。默认为 false
    68     /// </summary>
    69     [JsonProperty("exportHiddenObjects", NullValueHandling = NullValueHandling.Ignore)]
    70     public bool? ExportHiddenObjects { get; set; }
    71 
    72     /// <summary>
    73     /// 是否在userData中加入mepSystemType。默认为 false
    74     /// </summary>
    75     [JsonProperty("exportSystemType", NullValueHandling = NullValueHandling.Ignore)]
    76     public bool? ExportSystemType { get; set; }
    77 
    78     /// <summary>
    79     /// 是否在导出NWD的属性db文件。默认为 false
    80     /// </summary>
    81     [JsonProperty("exportProperties", NullValueHandling = NullValueHandling.Ignore)]
    82     public bool? ExportProperties { get; set; }
    83 
    84     /// <summary>
    85     ///  设置转换使用的单位,取值"ft""feet""英尺"采用revit默认的英尺为单位,默认以毫米为单位。默认为空
    86     /// </summary>
    87     [JsonProperty("unit", NullValueHandling = NullValueHandling.Ignore)]
    88     public string Unit { get; set; }
    89 
    90     /// <summary>
    91     /// 是否使用明细表内容。默认为 false
    92     /// </summary>
    93     [JsonProperty("exportSchedule", NullValueHandling = NullValueHandling.Ignore)]
    94     public bool? ExportSchedule { get; set; }
    95 }

    Rvt转换配置中很多选项都是有默认值的,如果手动设置的值与默认值相同,那么可以不用设置该项。

    为了简化显示请求body中的config配置项,在构造函数中将数值类型的配置项默认设置为 null,再配合 Newtonsoft.Json.dll

    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 属性,在序列化时可以不生成该项。

    (2) dwg模型

    对应封装成的C#实体类

     1 /// <summary>
     2 ///  dwg 模型配置项
     3 /// </summary>
     4 [Serializable]
     5 public class DwgModelConfig
     6 {
     7     /// <summary>
     8     ///  是否转成矢量图纸,默认为 true
     9     /// </summary>
    10     [JsonProperty("exportDrawing")]
    11     public bool ExportDrawing { get; set; }
    12 
    13     /// <summary>
    14     ///  是否导出pdf文件,默认为 false
    15     /// </summary>
    16     [JsonProperty("exportPdf")]
    17     public bool ExportPdf { get; set; }
    18 
    19     /// <summary>
    20     ///  是否导出缩略图,默认为 true
    21     /// </summary>
    22     [JsonProperty("exportThumb")]
    23     public bool ExportThumb { get; set; }
    24 }

    下面分别介绍常用的不同类型的文件转换场景

    1、DWG文件转换成矢量图纸

    请求 body(示例):

    {
        "source":{
            "fileId":1402934652281952,            // 文件ID
            "compressed":false                    // 文件是否为压缩文件
        },
        "priority":2,                             // 转换优先级
        "callback":"http://www.app.com/receive",  // 回调地址
        "config":null                             // 转换配置选项
    } 

    C#实现方法:

     1 /// <summary>
     2 ///  发起转换。将DWG文件转换成图片。
     3 /// </summary>
     4 /// <param name="accessToken">令牌</param>
     5 /// <param name="request">DWG文件转化的请求数据对象。根据实际需要设置对象里面的参数,不需要的参数不用赋值</param>
     6 /// <returns></returns>
     7 public virtual FileTranslateResponse TranslateDwgToPicture(string accessToken, DwgFileTranslateRequest request)
     8 {
     9     string data = request.SerializeToJson();
    10     return TranslateFile(accessToken, data);
    11 }

     其中调用的 TranslateFile()方法如下:

     1 /// <summary>
     2 ///  发起转换。
     3 ///  源文件上传成功后,即可发起对该文件的转换。由于转换不能立即完成,BIMFace支持在文件转换完成以后,通过Callback机制通知应用;
     4 ///  另外,应用也可以通过接口查询转换状态
     5 /// </summary>
     6 /// <param name="accessToken">令牌</param>
     7 /// <param name="data">请求体数据</param>
     8 /// <returns></returns>
     9 private FileTranslateResponse TranslateFile(string accessToken, string data)
    10 {
    11     //PUT https://api.bimface.com/translate
    12     string url = BimfaceConstants.API_HOST + "/translate";
    13 
    14     BimFaceHttpHeaders headers = new BimFaceHttpHeaders();
    15     headers.AddOAuth2Header(accessToken);
    16 
    17     try
    18     {
    19         FileTranslateResponse response;
    20 
    21         HttpManager httpManager = new HttpManager(headers);
    22         HttpResult httpResult = httpManager.Put(url, data);
    23         if (httpResult.Status == HttpResult.STATUS_SUCCESS)
    24         {
    25             response = httpResult.Text.DeserializeJsonToObject<FileTranslateResponse>();
    26         }
    27         else
    28         {
    29             response = new FileTranslateResponse
    30             {
    31                 Message = httpResult.RefText
    32             };
    33         }
    34 
    35         return response;
    36     }
    37     catch (Exception ex)
    38     {
    39         throw new Exception("[发起文件转换]发生异常!", ex);
    40     }
    41 }

    该方法在后面的几种模型转换中也会用到,是公用的方法。

    其中调用到的 httpManager.Put() 方法,请参考《C# HTTP系列》

    2、DWG文件转换成图片

    请求 body(示例):

    {
        "source":{
            "fileId":857482189666208,
            "compressed":false,
            "rootName":"root.dwg"
        },
        "priority":2,
        "callback":"http://www.app.com/receive",
        "config":{
                "exportDrawing":false             // 是否转成矢量图纸
        }
    }

    C#实现方法: 

     1 /// <summary>
     2 ///  发起转换。将DWG文件转换成图片。
     3 /// </summary>
     4 /// <param name="accessToken">令牌</param>
     5 /// <param name="request">DWG文件转化的请求数据对象。根据实际需要设置对象里面的参数,不需要的参数不用赋值</param>
     6 /// <returns></returns>
     7 public virtual FileTranslateResponse TranslateDwgToPicture(string accessToken, DwgFileTranslateRequest request)
     8 {
     9     string data = request.SerializeToJson();
    10     return TranslateFile(accessToken, data);
    11 }
    3、RVT文件转换成着色模式的效果

    请求 body(示例):

    {
        "source":{
            "fileId":857482189666208,
            "compressed":false,
            "rootName":"root.rvt"       // 如果是压缩文件,必须指定压缩包中哪一个是主文件
        },
        "priority":2,
        "callback":"http://www.app.com/receive",
        "config":null
    }

    C#实现方法:

     1 /// <summary>
     2 ///  发起转换。将RVT文件转换成着色模式的效果。
     3 /// </summary>
     4 /// <param name="accessToken">令牌</param>
     5 /// <param name="request">RVT文件转化的请求数据对象。根据实际需要设置对象里面的参数,不需要的参数不用赋值</param>
     6 /// <returns></returns>
     7 public virtual FileTranslateResponse TranslateRvtToRenderStyle(string accessToken, RvtFileTranslateRequest request)
     8 {
     9     string data = request.SerializeToJson();
    10     return TranslateFile(accessToken, data);
    11 }
    4、RVT文件转换成真实模式的效果

    请求 body(示例):

    {
        "source":{
            "fileId":857482189666208,
            "compressed":false,
            "rootName":"root.rvt"
        },
        "priority":2,
        "callback":"http://www.app.com/receive",
        "config":{"texture":true}                 // 转换时是否添加材质
    }

    C#实现方法:

     1 /// <summary>
     2 ///  发起转换。将RVT文件转换成真实模式的效果。
     3 /// </summary>
     4 /// <param name="accessToken">令牌</param>
     5 /// <param name="request">RVT文件转化的请求数据对象。根据实际需要设置对象里面的参数,不需要的参数不用赋值</param>
     6 /// <returns></returns>
     7 public virtual FileTranslateResponse TranslateRvtToRealStyle(string accessToken, RvtFileTranslateRequest request)
     8 {
     9     string data = request.SerializeToJson();
    10     return TranslateFile(accessToken, data);
    11 }
    5、RVT格式文件转换成具备二三维联动的功能

    请求 body(示例):

    {
        "source":{
            "fileId":1402934652281952,
            "compressed":false
        },
        "priority":2,
        "config":{
            "texture": false,        // 转换时是否添加材质
            "exportDwg": true,       // rvt2md是否导出dwg文件
            "exportPdf": true,       // dwg2md是否导出pdf文件
            "exportDrawing": true    // dwg2md是否导出mdv(矢量化图纸);取值为true时,exportDwg自动设置为true
        },
        "callback":"http://www.app.com/receive"
    }

    C#实现方法: 

     1 /// <summary>
     2 ///  发起转换。将RVT格式文件转换为具备二三维联动的功能效果。
     3 /// </summary>
     4 /// <param name="accessToken">令牌</param>
     5 /// <param name="request">RVT文件转化的请求数据对象。根据实际需要设置对象里面的参数,不需要的参数不用赋值</param>
     6 /// <returns></returns>
     7 public virtual FileTranslateResponse TranslateRvtTo23LinkStyle(string accessToken, RvtFileTranslateRequest request)
     8 {
     9     string data = request.SerializeToJson();
    10     return TranslateFile(accessToken, data);
    11 }
    6、其它三维模型文件转换:常规转换(不带材质)

    请求 body(示例):

    {
        "source":{
            "fileId":857482189666208,
            "compressed":false,
            "rootName":"root.skp"
        },
        "priority":2,
        "callback":"http://www.app.com/receive",
        "config":null
    }

    C#实现方法:

     1 /// <summary>
     2 ///  发起转换。其它三维模型文件转换,常规转换(不带材质)
     3 /// </summary>
     4 /// <param name="accessToken">令牌</param>
     5 /// <param name="request">其他三维模型文件,包括RVT格式文件转化的请求数据对象。根据实际需要设置对象里面的参数,不需要的参数不用赋值</param>
     6 /// <returns></returns>
     7 public virtual FileTranslateResponse TranslateOther3DModelToWithoutMaterialStyle(string accessToken, Other3DModelFileTranslateRequest request)
     8 {
     9     string data = request.SerializeToJson();
    10     return TranslateFile(accessToken, data);
    11 }
    7、其他三维模型文件包括RVT格式文件,需要转换出引用的外部材质场景、贴图等

    请求 body(示例):

    {
        "source":{
            "fileId":1234621112557376,
            "compressed":true,
            "rootName":"bimface_2018_打包材质&系统材质库.rvt"
        },
        "priority":2,
        "callback":"http://www.app.com/receive",
        "config":{"texture":true}
    }

    C#实现方法:

     1 /// <summary>
     2 ///  发起转换。
     3 ///  其他三维模型文件包括RVT格式文件,需要转换出引用的外部材质场景、贴图等
     4 /// (上传的文件必须为压缩包,压缩包内同级目录包含模型文件和关联的所有材质文件,转换时必须指定rootName为主文件)。
     5 /// </summary>
     6 /// <param name="accessToken">令牌</param>
     7 /// <param name="request">其他三维模型文件,包括RVT格式文件转化的请求数据对象。根据实际需要设置对象里面的参数,不需要的参数不用赋值</param>
     8 /// <returns></returns>
     9 public virtual FileTranslateResponse TranslateOther3DModelToWithMaterialStyle(string accessToken, Other3DModelFileTranslateRequest request)
    10 {
    11     string data = request.SerializeToJson();
    12     return TranslateFile(accessToken, data);
    13 }
     
    测试

    在BIMFACE的控制台中可以看到我们上传的文件列表,共计2个文件。

     

    下面以 rac_advanced_sample_project-三维视图 - From Parking Area.dwg 文件为例,测试“将DWG文件转换成矢量图纸”方法。

    在如下所示的测试页面中,DWG文件转换区域中,选择相关的转换参数,然后点击【将DWG文件转换成矢量图纸】按钮开始转换

    刷新控制台中的列表可以看到该文件的模型状态显示为“转换中”

    等待几秒或者几分钟后,该文件的模型状态显示为“转换成功”

    待BIMFace转换完毕后,根据应用传入的回调地址,BIMFace会通知转换结果,转换可能成功、也可能失败。

    查看服务器上配置的Callback处理程序记录的日志:

     
    Callback的配置与业务逻辑

    Callback的配置项如下:

    Callback机制与微信开发需要开发者提供开发者服务器的原理类似,用于开发者与第三方(BIMFACE、微信登)平台进行数据的回传与逻辑的交互。在ASP.NET开发模式下一般可以采取以下几种方式来设置:

    方式1:使用一般处理程序(.ashx) 处理业务逻辑的交互。

    方式2:建立 ASP.NET WebForm 程序,在具体的 WebForm 页面的构造函数中处理业务逻辑的交互。

    方式3:建立 ASP.NET MVC,通过控制器处理业务逻辑的交互。

    方式4:建立 ASP.NET 程序,通过 WebAPI 处理业务逻辑的交互。

    本示例种采用了第一种方式。

    Callback 传回以下参数:

    signature(签名):为了确保回调消息是由BIMFace发出的,应用在收到回调消息后,须验证签名。签名的计算方式:MD5(``appKey:appSecret:fileId:status:nonce''),如果应用计算的签名与BIMFace返回的签名一致,则证明该消息是安全可靠的。

    应用收到回调后,须向BIMFace发送回执,回执消息:HTTP STATUS 200

    BimFaceHandler的回调地址对应的完整逻辑方法如下:
     1     /// <summary>
     2     /// BimFaceHandler 的摘要说明
     3     /// </summary>
     4     public class BimFaceHandler : IHttpHandler
     5     {
     6         public void ProcessRequest(HttpContext context)
     7         {
     8             context.Response.ContentType = "text/plain";
     9             //context.Response.Write("Hello World");
    10 
    11             string appKey = ConfigUtility.GetAppSettingValue("BIMFACE_AppKey");
    12             string appSecret = ConfigUtility.GetAppSettingValue("BIMFACE_AppSecret");
    13             string uid = context.Request.QueryString["uid"];  // SparkBimFace
    14 
    15             #region 校验
    16             if (appKey.IsNullOrWhiteSpace())
    17             {
    18                 LogUtility.Error("BIMFace appKey 配置项没有配置!");
    19 
    20                 return;
    21             }
    22 
    23             if (appSecret.IsNullOrWhiteSpace())
    24             {
    25                 LogUtility.Error("BIMFace appSecret 配置项没有配置!");
    26 
    27                 return;
    28             }
    29 
    30             if (uid.IsNullOrWhiteSpace())
    31             {
    32                 LogUtility.Error("[非法请求]回调地址Url链接中的参数 uid 没有配置或者配置的值为空!");
    33 
    34                 return;
    35             }
    36             #endregion
    37 
    38             long fileId = context.Request.QueryString["fileId"].ToLong();  // 文件ID
    39             string status = context.Request.QueryString["status"];         // 转换的结果
    40             string reason = context.Request.QueryString["reason"];         // 若转换失败,则返回失败原因
    41             string thumbnail = context.Request.QueryString["thumbnail"];   // 缩略图地址
    42             string nonce = context.Request.QueryString["nonce"];           // 回调随机数
    43             string signature = context.Request.QueryString["signature"];   // BIMFACE的加密签名
    44 
    45            
    46             string callbackResponse = string.Format("fileId:{0},
    status:{1},
    reason:{2},
    thumbnail:{3},
    nonce:{4},
    signature:{5}",
    47                                                      fileId, status, reason, thumbnail, nonce, signature);
    48             string tip;
    49             string custCalcSignature;
    50             FileConvertApi api = new FileConvertApi();
    51             bool checkSignature = api.CheckCallbackSignature(appKey, appSecret, fileId, status, nonce, signature, out custCalcSignature);
    52             if (checkSignature)
    53             {
    54                 tip = "[BIMFace发出的回调信息签名验证成功!]"
    55                       + Environment.NewLine
    56                       + callbackResponse;
    57                 LogUtility.Info(tip);
    58 
    59                 //Todo 此处可以根据fileId把相关的信息写入数据库中
    60 
    61                 // 回执消息:应用收到回调后,须向BIMFace发送回执,回执消息:HTTP STATUS 200
    62                 context.Response.Write("HTTP STATUS 200");
    63             }
    64             else
    65             {
    66                 tip = "[BIMFace发出的回调信息签名验证不通过!]"
    67                     + Environment.NewLine
    68                     + callbackResponse
    69                     + Environment.NewLine
    70                     + "自定义计算签名 custCalcSignature:" + custCalcSignature;
    71 
    72                 LogUtility.Error(tip);
    73 
    74                 context.Response.Write(tip);
    75             }
    76 
    77             context.Response.End();
    78         }
    79 
    80         /// <summary>
    81         ///  该属性获得一个布尔值,指示另一个请求是否可以使用该HTTP处理程序的实例。
    82         /// <para>如果设置为true,能提高性能,但要注意线程之间安全性问题。如果设置为false,则线程是安全的</para>
    83         /// </summary>
    84         public bool IsReusable
    85         {
    86             get
    87             {
    88                 return false;
    89             }
    90         }
    91     }

    其中调用到的 CheckCallbackSignature()方法,用于验证BIMFace发出的回调消息签名信息是否安全可靠

     1 /// <summary>
     2 ///  验证BIMFace发出的回调消息签名信息是否安全可靠
     3 /// </summary>
     4 /// <param name="appKey">开发者秘钥</param>
     5 /// <param name="appSecret">开发者密码</param>
     6 /// <param name="fileId">BIMFace发出的回调信息:文件ID</param>
     7 /// <param name="status">BIMFace发出的回调信息:转换的结果</param>
     8 /// <param name="nonce">BIMFace发出的回调信息:回调随机数</param>
     9 /// <param name="signature">BIMFace发出的回调信息:签名</param>
    10 /// <param name="custCalcSignature">输出参数:根据BIMFACE平台的加密规则计算出来的签名信息</param>
    11 /// <returns></returns>
    12 public bool CheckCallbackSignature(string appKey, string appSecret, long fileId, string status, string nonce, string signature, out string custCalcSignature)
    13 {
    14     custCalcSignature = GetCallbackSignature(appKey, appSecret, fileId, status, nonce);
    15 
    16     return custCalcSignature == signature;
    17 }
     1 /// <summary>
     2 ///  获取BIMFace发出的回调消息签名信息
     3 /// </summary>
     4 /// <param name="appKey">开发者秘钥</param>
     5 /// <param name="appSecret">开发者密码</param>
     6 /// <param name="fileId">BIMFace发出的回调信息:文件ID</param>
     7 /// <param name="status">BIMFace发出的回调信息:转换的结果</param>
     8 /// <param name="nonce">BIMFace发出的回调信息:回调随机数</param>
     9 /// <returns></returns>
    10 public string GetCallbackSignature(string appKey, string appSecret, long fileId, string status, string nonce)
    11 {
    12     /* signature(签名):为了确保回调消息是由BIMFace发出的,应用在收到回调消息后,须验证签名。
    13      * 签名的计算方式:MD5("appKey:appSecret:fileId:status:nonce"),如果应用计算的签名与BIMFace返回的签名一致,则证明该消息是安全可靠的。 
    14      */
    15 
    16     return string.Format("{0}:{1}:{2}:{3}:{4}", appKey, appSecret, fileId, status, nonce).EncryptByMD5();
    17 }

    这里使用C#的自定义扩展方法 EncryptByMD5()

     1 /// <summary>
     2 ///  使用 MD5(不可逆加密) 算法加密字符串
     3 /// </summary>
     4 /// <param name="this">扩展对象。字符串</param>
     5 /// <param name="caseType">字符串大小写。默认小写</param>
     6 /// <returns></returns>
     7 public static string EncryptByMD5(this string @this, CaseType caseType = CaseType.Lower)
     8 {
     9     using (MD5 md5 = MD5.Create())
    10     {
    11         var sb = new StringBuilder();
    12         byte[] hashBytes = md5.ComputeHash(Encoding.Default.GetBytes(@this));
    13         foreach (byte bytes in hashBytes)
    14         {
    15             sb.Append(bytes.ToString("X2"));//X2 表示二进制
    16         }
    17 
    18         return caseType == CaseType.Upper ? sb.ToString() : sb.ToString().ToLower();
    19     }
    20 }
     
  • 相关阅读:
    读《大道至简》第二章有感
    《大道至简》读后感
    JAVA课后作业
    大道至简第三章观后感
    JAVA作业之两数的加减乘除
    JAVA作业之动手动脑
    第一次Java实验
    大道至简第二章观后感
    大道至简第一章观后感
    Django__admin的配置
  • 原文地址:https://www.cnblogs.com/SavionZhang/p/11451815.html
Copyright © 2020-2023  润新知