Edi Wang

Microsoft MVP for Azure

All Posts

Windows Phone 8 文本框如何限定软键盘类型

在开发Windows Phone应用时,一个非常通用的需求就是限定文本框的输入内容。最直接的办法是限定弹出的软键盘的类型。比如有些文本框只允许输入数字,那就弹出数字键盘,不让用户选择其他键盘。这样做的好处有两个:节省后台验证逻辑、方便用户交互。 要限定键盘类型,做法很简单,就是设置TextBox控件的InputScope属性。比如输入电话号码的文本框可以这样写: 这样弹出的文本框就是数字键盘: 所有的InputScope类型见下表: 翻译自MSDN:http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh393998%28v=vs.105%29.aspx 键盘 备注 InputScope 包括自动修正、建议和表情 Text 默认键盘 …
Windows Phone

针对IIS7以上的ASP.NET网站自定义错误页面与异常日志总结

自定义错误页面和异常记录是个很古老的话题了,但依旧可以让人爆到现在。在我做了无数次试验并总结经验和原则后,写下本文,已警后人。 本文的范围和限制 本文仅仅适用于部署在IIS7或以上版本中的ASP.NET 4.0集成模式应用程序。IIS7以上的意思是Windows Server 2008以上服务器适用。我已在WS2012R2,IIS8上测过。 本文的方法均适用于ASP.NET WebForm和MVC应用程序。 本文针对的问题 静态错误页面好还是动态错误页面好?我该如何设计ASP.NET网站错误处理? 我不希望错误页面后面跟上aspxerrorpath=…这个小尾巴。 我的自定义错误页面在VS里调试是好的,为什么部署到服务器上就出不来了? 我的自定义错误页面可以正常显示,但为什么返回的Http状态码不正确? 异常日志该怎样记录,有没有比较好的实践? 一、错误页面的选择 选择静态html页面 …
IIS

Windows Azure的计费方式和省钱的最佳实践

我从去年9月开始试用国内的Windows Azure,同时也有一个国际版Azure的账号。目前国内的Windows Azure还没有出台计费标准和细则,所以这篇文章里不会提及具体费用,但可以下载每月使用记录来观察和总结计费规律。国内的计费规则和Azure国际版是一样的,但是具体标准还没出来。写这篇文章的目的是总结一下我遇到的问题和经验,以帮助大家如何更经济的去使用Azure的服务。 一、计费周期和订阅 Azure的计费是跟着订阅走的,一个账户可以拥有多个订阅。我使用的主要是网站和虚拟机两个服务。就目前的情况来看,免费试用套餐一不小心就会超额被禁用。一旦订阅被禁用只能等到下个计费周期开始才能继续使用。比如我的订阅是9月9日开通的,那我的计费周期就是每月的9日到下月的8日。如果我在10月份超出了额度限制,那我在Azure上的所有服务都会暂停,并且要等到11月9日才能重新恢复。 被禁用的订阅前面 …
Azure

如何把网站及数据库部署到Azure上并绑定域名

国内的Windows Azure很快就要正式商用了,许多小伙伴们也有计划把现有的网站迁移到Windows Azure上去。但是国内相关的中文文档还是比较缺乏的,所以今天我就写了个超详细教程来教大家如何把ASP.NET网站部署到Windows Azure上。demo用的网站是带有数据库的,并且最后还会演示如何绑定一个.com域名到网站上。 我写的内容基本都是在Channel9上看来的,并且自己亲自实践过许多次的。大家现在阅读的这个博客就是用同样的方法部署到Windows Azure上的。所以不必担心文章坑爹。我的博客不像国内的许多网站那样,发表的内容都没自己测过,非常没有责任心。 下面进入正题。 1. 部署数据库 首先,假设我们的网站已经开发好了。这是一个带有一个SQL Server数据库的ASP.NET网站。第一步我们要做的,是把数据库部署到Windows Azure上去。 你需要的工具: …
SQL Azure DevOps

ASP.NET Web API 跨域访问(CORS)要注意的地方

前几天我在帮队友撸一个WebAPI的跨域访问问题,被爆出了翔,今天正好有时间总结一下经验。 首先一个最坑之坑,也是ASP.NET官网上都没有提到的坑,是Web.config里的配置。大家看这个建立WebAPI项目之后,默认的Web.config: 它居然把OPTIONS类型的请求给撸掉了!然而,在jQuery等框架里发起CORS请求的时候,虽然你写的可能是“GET”,但是现在的浏览器是会自动把这个GET先撸成OPTIONS去访问服务的,这也叫“preflight”请求。如果你的服务拒绝OPTIONS这个verb,你会得到一个405的结果(用fiddler就可以看到)。 所以,要让WebAPI支持CORS,第一步就是在web.config里把“”删掉。 接下来,要实现CORS,有两种办法。一是在客户端完成(要求对WebAPI做少量拓展),二是在服务端(WebAPI)本身做支持。 一、客户端 …
ASP.NET Web API CORS

在IIS服务器上安装和配置Web Deploy (WS2008R2)

作为ASP.NET开发者,部署应用到测试或生产环境是家常便饭。不知道大家平时都是怎么部署网站的?手工拷贝文件?FTP?还是高端的package解压?对我来说,最方便的还是WebDeploy,它可以让我从Visual Studio中一键部署网站到IIS服务器,并且智能判断哪些文件是新增的,哪些是需要修改或删除的。Windows Azure Website就默认支持这样的部署方式。但我们不可能一直在公有云上做开发,如果我们想把这样方便的功能带到本地怎么办呢? 经过开荒,我在Windows Server 2008 R2和Windows Server 2012 R2上都成功配置了Web Deploy。目前用的最多的还是WS2008R2,所以我就带大家来看看如何在这款系统上安装和配置Web Deploy。 首先,你需要在IIS上安装管理服务。 在Server Manager(服务器管理)里面,展开 …
IIS

Kendo UI for ASP.NET MVC 的一些使用经验

最近的项目里用到了Kendo UI。这货很好很强大,但可惜官方文档组织的并不是很好,有很多配置非常坑,需要自己去发掘。 一、版本 首先,是版本的区别。简单的来说,免费版的Kendo UI是不包含DataViz组件的,即没有图表功能,并且也没有服务端的Helper,比如MVC的wapper,所以,免费版只有js和css,不会给你dll的。 收费版,比如for MVC的这个版本,除了包含dataviz以外,还包含预先定义好的mvc wapper,所以你需要引用dll才能使用kendo的html helper。这些Helper的功能仅仅是生成对应的JS,对于熟悉C#的程序员来说,图个方便而已。不过不得不承认,这些helper的设计是一流的,使用lambda表达式来配置参数感觉非常棒。 总结一下,如果你的团队前端程序员非常碉,你可以使用免费版,但不包含图表组件。如果你是像我一样的屌丝ASP. …
ASP.NET MVC Kendo UI

ASP.NET WebAPI 自动生成帮助文档

目前在做的项目里要用到RESTful Service,一开始是用WCF WebHttpBinding撸的,但我知道WebAPI才是最适合的,正好现在VS2013 RTM了,Web API 2也跟着ASP.NET MVC5一起发布了,于是今天就把Service用Web API 2重写了一下。 我选择Web API的一个重要原因就是因为可以自动生成文档,省去了开发人猿不少宝贵的时间。以前在用Web API第一代的时候,自动生成帮助文档的功能默认是不完整的,现在到了Web API 2,这个功能已经通过NuGet包的形式很好的整合到了一起。我们来看一下吧! 首先,用VS2013创建的Web API 2项目会默认带有Microsoft ASP.NET Web API Help Page的包。如果没有,就需要手动去NuGet上安装。 在安装了这个包以后,你的Web API项目目录里会多一个
ASP.NET Web API

如何让应用程序要求以管理员身份运行(C#)

从Windows Vista开始,为了防止操作系统被恶意软件破坏,Windows加入了UAC机制,在没有关闭UAC的时候,用户的程序都没有管理员权限去执行。但是如果软件需要做一些操作,比如读写注册表,就需要以管理员身份启动。然而普通用户并不清楚这一点,这有可能导致我们的程序被差评。幸好,用.NET开发的程序可以很方便的做到自动要求以管理员身份运行。首先为了达到演示效果,我需要在程序界面上通知当前环境是不是以管理员身份运行,为此我找了一个UACHelper,这个东西挺实用的,就算不是以管理员身份运行的,也不会在用户面前直接爆掉。
C# Windows UAC

巧用委托简化重复代码

在C#编程中通常会碰到许多重复劳动的情况,而面向对象编程的原则就是消除这些重复劳动,增加代码重用性。我们虽然有很多基本的模式去做抽象和封装,但还是会碰到一些看似不得已的重复劳动的情况。比如你在写一个数据访问层的类,按照规范,每个方法都需要加try-catch,就像这样: public void Method1() { try { // logic... } catch (DataException ex) { // fuck the ex... } } public void Method2() { try { // logic... } catch (DataException ex) { // …
C# lambda Delegate