活久见:有些异常是不能被catch(Exception)捕获的,你得把catch参数去掉

作者:V君 发布于:2017-6-14 0:25 Wednesday 分类:折腾手记

TL;DR: 

当你发现本应被捕获的异常却被无视 try-catch 语句时,

你应该试着去掉 catch(Exception ex) 中高亮的部分

写成 try {....} catch{....} 这种写法将不能直接取得异常实例,

你可以将上下文对象值记录下来作为排查线索。


本例:

将 MVC 5.2.3 站点部署到装了 mono 4.2.2 的Debian@树莓派。

首先就遇到一大堆兼容性问题。去掉一系列不兼容的组件。

(ApplicationInsights系列、CodeDom系列

总算能报出些看起来有点线索的异常。

System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.
  at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (System.Reflection.Assembly,bool)
  at System.Reflection.Assembly.GetTypes () <0x721db540 + 0x00023> in <filename unknown>:0 
  at Ease.Ioc.IocManager.RegisterInterface (System.Reflection.Assembly[] assemblies, System.Type iface,
System.Func`1 lifetimeManager) <0x721db0c0 + 0x000fb> in <filename unknown>:0 
  at Ease.Ioc.IocManager..ctor () <0x721fb130 + 0x00283> in <filename unknown>:0 
  at Ease.Ioc.IocManager..cctor () <0x721faff8 + 0x00027> in <filename unknown>:0 

这是模仿 ABP 在当前应用域中的所有程序集中寻找实现了指定接口的类,然后加到 IoC 容器。

(哎……谁让 ABP 还不支持 mono 呢。。。)

在对某个程序集调用 GetType 时爆炸了……

于是在其周围加上常规异常处理 try-catch(Exception) 试图找出有问题的程序集。

然而异常依旧引发,就跟没写 try-catch(Exception) 一样……

试着调整方法结构,避免一些在首次访问方法就引发异常的状况 —— 无果……

心一横,去掉 catch 语句的参数,记下当前调用 GetTypes 的程序集。

try
{
types.AddRange(asm.GetTypes().Where(p => false == p.IsAbstract && false == p.IsInterface && iface.IsAssignableFrom(p)));
}
catch
{
throw new Exception("Asm load fail?" + asm);
}

功夫不负有心人 or 瞎猫撞上死耗子? bingo! 抓到你啦!

Asm load fail?System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35

咋办? 没办法哇! 试着把引用干掉看看吧…… 果然就没事儿了!

稍稍去了解一下那玩意儿,发现是一堆辅助类, 反正一时半会也用不上。


于是就这样,用作类似 Hello world 的站点首页就成功呈现出来啦!

 —— 尽管是乱码…… 因为偷懒直接输出 Content 嘛! 接下来可以慢慢折腾啦!

标签: 软件开发 树莓派 C# linux mono 运行时错误

评论(0) 引用(0) 浏览(1540)

巧用「嵌入资源」和「动态加载程序集」解决依赖库版本冲突

作者:V君 发布于:2017-4-1 14:39 Saturday 分类:填坑经验

太短(?)就不写摘要了 (´∀((☆ミつ


一个老项目,使用了 .net 3.5,框架体系中已经引用了较早期的 Newtonsoft JSON 库

它的版本也是3.5现在这个库已的版本已经到10.0了

和旧版比起来有一些命名差异以及修复了一些 bug,需要的功能正好在被修复的 bug 里


我们都知道如果一个项目里不同的程序集之间引用不同版本但名称相同的程序集会出现冲突


尽管可以重定向程序集版本,但是那时还没啃透

不知道除了能代替版本还能指定另一个文件,这种方式也是可以解决问题的(MSDN)这是后话


回到我们这次的做法

新版本的 DLL 没跑进 bin试着手动复制进去(当然已经改过文件名再引用),发现启动不了

这是当然的,WEB 项目会无脑的把bin里的程序集全部都加载起来,发现同程序集名不同版本就挂了


于是就用了 Aio1ef 那招

 -- 引用时去掉本地复制,在首次使用前于静态构造加挂程序集解析事件,载入嵌入程序集


于是就让两个不同版本的 Newtonsoft JSON 共存了

当然目前只是在这个项目里的不同程序集分别引用


要在同一个程序集里引用两个名称相同,版本却不同的程序集

在没有用到 Attribute 的前提还是可以勉强反射一下实现写个类 Proxy 也是挺有意思的

如果有用到 Attribute 那就洗洗睡吧, 那估计要用 IL 显式指定程序集名称了 乂目


标签: 软件开发 C#

评论(0) 引用(0) 浏览(1695)

这不是BUG,是特性!——记一次 .NET C# 有/无符号字节数组非预期拆箱

作者:V君 发布于:2017-3-23 18:43 Thursday 分类:挖坑经验

TL;DR

检查可能是有符号字节数组的装箱对象要用 that.GetType() == typeof(byte[])

而不是 that is byte[] ,这和 CLR 实现机制有关. 似乎运行时不区分 byte[] 和 sbyte[]

装到 object 里的字节数组不管有无符号都能分别被有无符号数组拆箱出来...


扯扯:

处理一系列温度探头数据. 为了减小数据占用, 在检查了数值范围之后

选用了 sbyte 作为存储数据类型, 然而在自动可视化处理时被当做了无符号数组处理.

无符号数组一般表示二进制数据, 于是把温度以十六进制显示到界面上了. 好尴尬.

咕狗一把才发现原来还有这回事.

好吧 我就说一直以强类型自居的我大井怎么会有这么弱智的问题 _(:з」∠)_

标签: 软件开发 C# bug

评论(0) 引用(0) 浏览(1561)

解决一蛋痛的WCF-REST配置问题:未找到注册基址方案

作者:V君 发布于:2017-3-14 20:12 Tuesday 分类:挖坑经验

状况:

访问时出现以下错误

找不到具有绑定 WebHttpBinding 的终结点的与方案 http 匹配的基址。注册的基址方案是[]

注意, 注册的基址方案是空的, 和遍地都是的 “注册的基址方案是[http]”不同

 

TL;DR:

在 web.config 配置基址前缀就能解决该问题.

<serviceHostingEnvironment>

    <baseAddressPrefixFilters>

        <add prefix="http://localhost" />

    </baseAddressPrefixFilters>

</serviceHostingEnvironment>

扯扯:

扯你妹不想扯了, 花了好大劲都解决不了. 

结果 ServerAdmin 告诉咱们想起以前的项目遇到类似的情况时,负责人的做法...


so.解决不了配置问题的码农不是好运维? ( ゚∀。)

 

标签: 软件开发 C# ASP.NET MVC WCF REST 运行时错误

评论(0) 引用(0) 浏览(1346)

软件开发辅助工具 - 将EntityFramework实体文档注释搬进数据库(MSSQL)

作者:V君 发布于:2017-1-9 21:22 Monday 分类:我的应用

TL;DR
[ 本体 ][ 源代码 ]

效果:生成SQL用于更新表和字段说明.
用法:直接运行,在弹出的打开对话框选择定义实体的程序集. (记得启用XML文档生成)
限制:尚不明确.
环境:需要.NET 4.5.2以上, 作为开发者不需要啰嗦更多.


 

扯扯:

 

点击查看原图

 

点击查看原图

 

虽然用上Code-first之后各种便利,然而当需要生成数据库注释用来给运维之类的提供方便时.
咕狗了之后发现并没有现成的工具,懵逼了一会儿. 又查了一下更新数据库注释的方法.
嗯嗯 MSSQL 比 MySQL 做起来方便多了. 于是这个小工具就诞生辣.


首先将打开对话框指定的程序集载入

 遍历所有类 -> 筛选出有[TableAttribute]特性定义的类
  遍历属性 -> 筛选出可读可写的非导航属性
 收集表名,成员名(如果指定了Column特性,将取其指定的列名)

 按对应定义抓取XML文档里的注释

 基于上述信息构建数据库更新SQL脚本. 
  (由于M$SQL新增和更新的分别是两个存储过程, 于是简化处理, 先新增再更新. 
   ((报已存在的错误提示无视掉就可以了 _(:з」∠)_

 将SQL输出到窗体控件

由用户自行丢进SSMS执行,结束.


做这东西过程中遇到了几个有趣的现象, 尽管不是很高深.


0) 嵌套类全名用加号分隔类名
 但是XML文档中仍然是用点分隔类名

1) 基类在不同的程序集
 这时候就要按属性信息的定义类(DeclaringType)去找程序集对应的XML来读取注释了

2) 继承来自泛型的成员
 在XML中泛型以"MyGenericClass`1"的方式表示,
 需要区分泛型然后获取泛型定义(GetGenericTypeDefinition)
 再读取全名才能得到XML中的名字格式,
 如果直接取全名将会得到类似"MyGenericClass[Int32]"的格式.



标签: 软件开发 C# 数据库 ORM

评论(0) 引用(0) 浏览(1542)

Powered by emlog 去你妹的备案 sitemap