阿里云ECS邮件发送失败原因

首先这不是个技术问题,是没仔细阅读阿里云的产品帮助。

问题的现象:调用阿里云的邮件推送服务,本地程序没有任何问题,发布到阿里云的服务器,邮件发不出去了。

花了点时间看帮助,才知道目前阿里云的ECS服务器均已默认关闭了25端口,如果您的发送程序部署在阿里云 ECS 上,不勾选 SSL 时,使用 80 端口;勾选 SSL 时,使用 465 端口。

阿里云的邮件推送在线帮助:https://help.aliyun.com/document_detail/29449.html

最近的感触:没事不要炒股

最近出现的几个事情,给我带来的感触:

1、炒股会把心情炒坏,把心情炒没,大脑不正常,容易在与人沟通时代入自己的处境,做出匪夷所思的举动。

2、满嘴跑火车的人,要慎重交往。要坚信:言行一致的人少之又少。

3、优秀的销售的应该是“能说会道”,给客户至少70%的说话机会,自己把握住20%就足够了。

4、经常复盘和换个角度思考,把自己该做的做好,一切随之而来。

5、不贪小便宜,时刻提醒自己,不提醒就会忍不住。

旺财C# .NET代码生成器支持DTcms MySQL版生成了

昨天跟一资深老用户沟通之后,发现DTcms MySql版用得人越来越多了,整个运行于Linux主机下,比一定要Windows和MSSQL数据库的要求降低了很多,优势太明显。

于是昨晚加班,国庆假期前,搞定如下升级:

1、完成MySql.Data.dll更新

消除了报错:MySql.Data.MySqlClient.MySqlException:Fatal error encountered attempting to read the resultset,以便支持较新版本的MySql数据库。

2、完善读取MySql数据库的表列表和字段属性的脚本

SELECT table_name TableName,TABLE_COMMENT TableDescription
FROM INFORMATION_SCHEMA.TABLES WHERE table_type = ‘base table’
ORDER BY table_name

SELECT CASE ORDINAL_POSITION WHEN 1 THEN TABLE_NAME ELSE ” END TableName,
ORDINAL_POSITION 序,COLUMN_NAME ColumnName,
CASE EXTRA WHEN ‘AUTO_INCREMENT’ THEN ‘Y’ ELSE ” END IsIdentity,
case COLUMN_Key when ‘PRI’ then ‘Y’ else ” END PrimaryKey,
DATA_TYPE DataType,
CASE DATA_TYPE
WHEN ‘double’ THEN NUMERIC_PRECISION
WHEN ‘decimal’ THEN NUMERIC_PRECISION
WHEN ‘tinyint’ THEN NUMERIC_PRECISION
WHEN ‘int’ THEN NUMERIC_PRECISION
WHEN ‘bigint’ THEN NUMERIC_PRECISION
ELSE CASE WHEN CHARACTER_MAXIMUM_LENGTH IS NULL THEN 0 ELSE CHARACTER_MAXIMUM_LENGTH END
END ByteLength,
CASE DATA_TYPE
WHEN ‘double’ THEN NUMERIC_PRECISION
WHEN ‘decimal’ THEN NUMERIC_PRECISION
WHEN ‘tinyint’ THEN NUMERIC_PRECISION
WHEN ‘int’ THEN NUMERIC_PRECISION
WHEN ‘bigint’ THEN NUMERIC_PRECISION
ELSE CASE WHEN CHARACTER_MAXIMUM_LENGTH IS NULL THEN 0 ELSE CHARACTER_MAXIMUM_LENGTH END
END Length,
IFNULL(numeric_scale,”) IsNumeric,
CASE is_nullable WHEN ‘YES’ THEN ‘Y’ ELSE ” END AllowNull,
column_default DefaultValue,
COLUMN_COMMENT Description
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = ‘tableName ‘

3、增加DTcms4/5 MySql版DAL生成

生成到新目录:DTcms.DAL.MySql,2个模板,同时支持DTcms4和DTcms5两个版本。

4、发布V20181001国庆版

5、下一步计划整理在线版的帮助文档

图文和视频汇总在一起,并增加开发实例视频教程

Infor LN ERP中1个物料2个供应商同时供货,不分配采购订单

概念:
Sourcing percentage – A percentage used to calculate how orders are divided among suppliers.

故事背景:

供应商 A,Sourcing Percentage: 60%,MOQ: 25,Lead Time:90,Priority:999,供应商状态正常,没有特殊设置
供应商 B,Sourcing Percentage:40%,MOQ:30,Lead Time:90,Priority:999,供应商状态正常,没有特殊设置
大概1年前修改为此设置,从那以后,订单再也没有分配给B。

数据分析:

拉出采购订单明细,发现几十个采购订单下单数量最多时才65个。

原因分析:

假设订单量为100,那么A分配60,B分配40,并且都大于各自的MOQ,可按照预期下单。

假设订单量为20,那么小于任何一个供应商的MOQ,没办法生成订单。

假设订单数量为50,那么A分配30,B分配20,但B的MOQ为30,无法下单,只能全部下给A,50个。

原理分析:

但从数量上来看,要做到能够按照设定的比例分配数量,那么需求数量的最小值应该为:MAX(30/40%,25/60%),即75个。

解决办法:

理论上一个产品的最小订单量可以谈到2个供应商一致,类似交期、价格等。

当订单量小于允许分配的最小分配量时,两者优先级设为不一致。

从源头控制,针对需求和预测,做到订单数量可被分配。

其它我不知道的方法。

可能通过这种思路也无法解决,只能改变模式,分周期设置主供应商。

C# .Net中获取Windows AD域用户缺失的故障解决

因为公司的OA系统使用的Windows域账号集成认证,近期新来的同事账号却没能自动导入账号到OA系统,花了快一天时间发现并解决了问题。

Windows AD域用户清单获取不全,原来这里的写法有问题:ds.Filter = “(objectClass=user)”改为ds.Filter = “(&(objectClass=user))”

尽管问题很简单,但因此收获了一篇很全面的关于在C#中访问活动域的技术文章,原文地址:Howto: (Almost) Everything In Active Directory via C#

好文分享:ASP.NET WebForm设计思路的思考

博客园的荆棘人写了篇关于WebForm的文字,要知道这么古老的技术已经很好有人提及:https://www.cnblogs.com/Tpf386/p/9588243.html

更可怕的消息是,对于我这样的ASP时代的高手,肯定没有错过WebForm。是的我一直在用,不过更多的是用html+js+ashx+WebForm,只是轻量的用到WebForm的一些控件如:GridView和Repeater。

当然了,我们都要往前走,跳过MVC 3、4、5,直接玩.NET Core MVC是更好的选择。

 

用HttpContext.Current.Cache还是HttpRuntime.Cache

今天不说.NET Core里的新MemoryCache(Microsoft.Extensions.Caching.Memory),说说目前用得最广泛的.NET Framework下的缓存。

  1. HttpRuntime.Cache在非Web环境也支持,如WinForm、WPF
  2. HttpContext.Current.Cache只能用在Web中

MSDN上的解释如下:
HttpContext.Current.Cache:为当前 HTTP 请求获取Cache对象。
HttpRuntime.Cache:获取当前应用程序的Cache对象。
为一探究竟,我们用.NET Reflector看看HttpContext.Cache和HttpRuntime.Cache的源码:

//System.Web.HttpContext.Cache属性实现
public sealed class HttpContext
{
public Cache Cache
{
get
{
return HttpRuntime.Cache;
}
}
}

//System.Web.HttpRuntime.Cache属性实现
public sealed class HttpRuntime
{
public static Cache Cache
{
get
{
if (AspInstallDirectoryInternal == null)
{
throw new HttpException(SR.GetString(“Aspnet_not_installed”, new object[] { VersionInfo.SystemWebVersion }));
}
Cache cache = _theRuntime._cachePublic;
if (cache == null)
{
CacheInternal cacheInternal = CacheInternal;
CacheSection cacheSection = RuntimeConfig.GetAppConfig().Cache;
cacheInternal.ReadCacheInternalConfig(cacheSection);
_theRuntime._cachePublic = cacheInternal.CachePublic;
cache = _theRuntime._cachePublic;
}
return cache;
}
}
}

通过源码我们可以看出:HttpContext.Current.Cache是通过调用HttpRuntime.Cache实现的。

那么两者到底有没有区别的?既然两个指向的是同一Cache对象,两者的差别只能出现在HttpContext和HttpRuntime上了。

我们再来看看MSDN对HttpContext和HttpRuntime的定义:
HttpContext:封装有关个别HTTP请求的所有HTTP特定的信息,HttpContext.Current为当前的HTTP请求获取HttpContext对象。
HttpRuntime:为当前应用程序提供一组ASP.NET运行时服务。

通过上面的定义可以看出:HttpRuntime.Cache相当于就是一个缓存具体实现类,这个类虽然被放在了System.Web命名空间下,但是非Web应用下也是可以使用。HttpContext.Current.Cache是对上述缓存类的封装,由于封装到了HttpContext类中,局限于只能在知道HttpContext下使用,即只能用于Web应用

#0001:Done is better that perfect,比完美更好的是完成

Done is better that perfect并非Facebook CEO原创,但因为他说出来而被大家所知。中文直译就是标题所说的:比完美更好的是完成,但我觉得翻译为:比完美更重要的是完成,更好些。

我开发软件的经历

在我过往软件从业经历中不仅做过基于原有知名产品的二次开发,也有真正从零开始的产品开发。这里所说的产品包括:网站、有人机交互的应用软件、纯后台的程序、功能插件、APP等。有那么几年,一直觉得自己做得东西太小、或者不成熟、或者不强大,不敢给真正需要的人、企业去用,从而躺在自己的硬盘里或者只给唯一少数用户带来利益。

记得2013年,我和TonySiko、Jack曾经就是否要做自己的产品这个问题而犹豫不决,最大的困难来自思维局限,认为一定要做堪比市面上已经成百上千人开发多年的成熟产品,其实后来想开了,就从小的开始:小插件、小应用、小程序、小系统,解决用户的小问题、小公司的问题、小范围的问题等。

2014年起,开始为邻居的珠宝公司优化运营流程,开发针对电商的库存管理运营平台,并持续3年才完成覆盖线上电商和线下实体批发业务的业务系统。从2015年起,陆续推出多个FlowPortal插件、DTcms插件,并在淘宝销售,2017年推出基于针对DTcms的代码生成器,同期也将以前写网站的经验和积累,弄成建站平台。2018年把自己看到的很多企业运营中常见的问题归类,并提出自己的解决方案,围绕这些主题开发一些小软件产品,是我目前的定位和方向,毕竟第一是只有我一个人开发,第二做帮用户解决问题的方案中,软件只是一部分。软件背后的逻辑、嵌入其内的流程、简洁的用户体验界面、基于系统所存储的数据(Data)而带给用户的信息(Information),才是最有价值的地方。

为何不要上来追求完美

用过Windows的人都知道要打补丁,也知道这个Windows从95、98、Me、2000、xp、7、10、2013、2012、2016、2019,从未停止升级。

既然这么大软件公司,都是在一个固定期限段追求完成,然后后继再来完善、完美。那么对于小软件公司、个人开发者,又有什么财力能支撑我们上来就追求完美。相信扎克伯格也深谙此道。

不管你的的目标有多么的高远,引领市场、行业No1的前提都是你必须活着,远景对倒闭的企业和组织没有任何意义。

饼可以画,但是生存盈利还是当前最重要的。尽管不完美,功能还只是实现基本功能,用户操作也不是很方便,质量稳定性也不是很好,可维护性可调试性需求也没有考虑,但是解决了客户棘手的问题,更多功能需求、更好用户体验以及售后维护等等都可以在推出产品之后通过用户反馈、市场验证来逐步的完善。这也是我们经常说的软件和互联网都需要有迭代过程的。

看到这里,你是否也认同,应该先完成“无中生有”,不应该上来就“长达成人”后才出来见人。相信有很多有想法、有技术的年轻人,因为这个顾虑,慢慢熬成了中年油腻男,最后连想的勇气都没有了。

立即开始,先做出来

如果,你也和我一样:使用大型、传统软件多年;在企业里熟知各环节的业务流程,并对痛点有感触,有流程优化和自己解决的能力,不妨停止恐惧,即刻开始。不要被下面这个复杂的软件开发常规流程所吓倒。

从一个不完美的小功能开始,实实在在解决多数公司会遇到的问题。然后持续付出、不断完善,直至完美功能、完美产品。

我的那些已经完成但不完美产品

前几年的大家可以上我的淘宝店,以插件为主。下面几个是我将近3年的积累整理、优化所做的。

  1. 旺财C# .NET代码生成器 – 针对技术人员,也为自己的快速开发平台配套的,提高开发效率的利器,没有它,我哪有这么多精力做下面的软件。
  2. 旺财云库存 – 针对中小型企业,特别是有一物一码(一码一物)、批次、质保期、有效期要求的金银珠宝、化妆品行业。
  3. 旺财云进销存 – 针对中小型企业,没有ERP系统
  4. 旺财供应商门户 – 针对大中型企业,对接ERP,与下游供应商进行订单协同,未来扩展询价、投标、质量跟踪协作等。
  5. 旺财客户门户 – 针对大中型企业,对接ERP,利用移动互联网将库存开放给客户、经销商,方便其利用移动互联网和传统PC浏览器进行下单并跟踪、协同订单全流程。

这些产品都有核心并可实施,目前仅放出了旺财云库存和旺财云进销存的演示系统,预计很快就会将供应商平台演示系统开放出来。

从0到0.1

如本文标题所说:不求完美,只求完成。也许我这里的“完成”只是完成了从0到0.1,这些产品如能被越来越多的用户用在他们的日常工作当中,提高效率、节约成本、创造价值,那我将会更加持续付出精力,来完善、完美它们。

也许你会问,你为什么选择做这些产品呢?后面的系列,我会陆续分享我的想法。

.NET Core 3要支持WinForm和WPF,你准备好了吗?

一早打开VS 2017,发现8月8号就发布的消息,的确有些兴奋:.NET Core 3在路上,并且要支持WinForm和WPF了。

我用官方提供的工具测试了一下旺财C# .NET代码生成器,截图如下:

结果DotNet.Utilities还有近9%需要调整适配.NET core.

原文地址:https://blogs.msdn.microsoft.com/dotnet/2018/08/08/are-your-windows-forms-and-wpf-applications-ready-for-net-core-3-0/?utm_source=vs_developer_news&utm_medium=referral

有空加一下

近期被多人在微信、QQ问些Infor ERP LN问题,最后不欢而散。

问得人觉得,他很客气和礼貌的询问了我是否有空、是否愿意回答,觉得理所当然。而他们不知道,我碍于面子,没有直接回绝。

当我问对方是否加入了我创办的Infor ERP LN私房菜的时候,对方居然都会有一样的回答:有空加一下

看到这句话,我知道他不会加入,哪怕免费都不会。因为有些问题,我让他看我博客的分享,他都不愿意行动。

他以为我是要他的99元终生的会费,他不知道的是我在评估自己:看我义务回答了问题的时间,对别人是否有价值。

我坚信自己所做的事情是有价值的,相信只有你产生了价值认可,彼此才会共享价值。

从今以后,不再理所当然的回答任何人的LN问题。我会说:有空回你

不是我吓唬你,还没加入的,赶紧啦!