[转载]ASP.Net MVC探索之路 Model的比较验证

mikel阅读(1131)

[转载]ASP.Net MVC探索之路 – Model的比较验证 – Catcher In The Rye – 博客园.

WebForm有一个比较验证服务器控件CompareValidator ,可以比较两个控件的值大小或一个控件与某一个具体值的大小。可以进行string,int,double,DateTime,decimal这些数据类 型的==、!=、>、<、>=、<=比较。在ASP.NET MVC 2.0中,我们已经可以使用基于DataAnnotations的校验方式,对Model的值进行空校验(Required)、范围校验(Range)、 字符串长度校验(StringLengthAttribute)等。在ASP.NET MVC 3中,我们还可以使用CompareAttribute进行简单的相等(==)校验,但仅此而已,其他校验就没有了。
这里我们定义一个类似WebForms验证服务器控件CompareValidator的Attribule。

首先定义一个枚举表示我们要比较的数据类型:

public enum ValidationDataType : byte
{
String,Integer,Double,Date,Currency
/*Decimal*/
}

再定义一个枚举表示比较方式:

public enum ValidationCompareOperator : byte
{
Equal, NotEqual,GreaterThan,GreaterThanEqual,LessThan,LessThanEqual
}

然后当然就是主角CompareAttribute:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class CompareAttribute : ValidationAttribute
{
public string SourceProperty { get; private set; }
public string OriginalProperty { get; private set; }
public ValidationCompareOperator Operator { get; private set; }
public ValidationDataType Type{ get; private set; }

private const string _defaultErrorMessage = ‘{0}’ 与 ‘{1}’ 进行 {2} 比较失败;

public CompareAttribute(string sourceProperty, string originalProperty
, ValidationCompareOperator op, ValidationDataType type)
:
base(_defaultErrorMessage)
{
SourceProperty
= sourceProperty;
OriginalProperty
= originalProperty;
Operator
= op;
Type
= type;
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
SourceProperty, OriginalProperty, Operator.ToString());
}

public override bool IsValid(object value)
{
PropertyDescriptorCollection properties
= TypeDescriptor.GetProperties(value);
object sourceProperty = properties.Find(SourceProperty, true /* ignoreCase */)
.GetValue(value);
object originalProperty = properties.Find(OriginalProperty, true /* ignoreCase */)
.GetValue(value);

return compare(sourceProperty,originalProperty);
}

private bool compare(object sourceProperty, object originalProperty)
{
int num = 0;
switch (this.Type)
{
case ValidationDataType.String:
num
= string.Compare((string)sourceProperty
, (
string)originalProperty, false, CultureInfo.CurrentCulture);
break;

case ValidationDataType.Integer:
num
= ((int)sourceProperty).CompareTo(originalProperty);
break;

case ValidationDataType.Double:
num
= ((double)sourceProperty).CompareTo(originalProperty);
break;

case ValidationDataType.Date:
num
= ((DateTime)sourceProperty).CompareTo(originalProperty);
break;

case ValidationDataType.Currency:
num
= ((decimal)sourceProperty).CompareTo(originalProperty);
break;
}
switch (this.Operator)
{
case ValidationCompareOperator.Equal:
return (num == 0);

case ValidationCompareOperator.NotEqual:
return (num != 0);

case ValidationCompareOperator.GreaterThan:
return (num > 0);

case ValidationCompareOperator.GreaterThanEqual:
return (num >= 0);

case ValidationCompareOperator.LessThan:
return (num < 0);

case ValidationCompareOperator.LessThanEqual:
return (num <= 0);
}
return true;

}
}

在Model中就可以这样使用了,以下校验两次输入的密码是否一致:

[Compare(PasswordConfirm, Password, ValidationCompareOperator.Equal
,ValidationDataType.String, ErrorMessage
= 请确认两次输入的密码一致)]
public class UserInputEdit
{
[DisplayName(
登录密码)]
public string Password { get; set; }

[DisplayName(确认密码)]
public string PasswordConfirm { get; set; }
}

如果果要Model中有两个时间,开始时间和结束时间,要求结束时间必须大于开始时间:

[Compare(TimeEnd, TimeStart, ValidationCompareOperator.GreaterThan
, ValidationDataType.Date, ErrorMessage
= 结束时间必须大于开始时间)]
public class UserInputEdit
{
[DisplayName(
开始时间)]
public DateTime TimeStart { get; set; }

[DisplayName(结束时间)]
public DateTime TimeEnd { get; set; }
}

ASP.NET MVC 3也有一个CompareAttribute,但它只能进行Equals比较。同样的比较两次密码是否一致,以上代码可以写成这样:
public class UserInputEdit
{
[DisplayName(
登录密码)]
public string Password { get; set; }

[DisplayName(确认密码)]
[Compare(
Password, ErrorMessage = 请确认两次输入的密码一致)]
public string PasswordConfirm { get; set; }
}

在 我们自定义的CompareAttribute中,必须将Attribute应用于class上。如果您想像ASP.NET MVC 3中,将标记写在属性,很遗憾不行。因为ValidationResult IsValid(…)的方法在.Net 4.0才有,MVC 3也才有相应的支持。当然也可以修改我们自定义的CompareAttribute,但请注意以下代码我没测试过:

代码

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field
, AllowMultiple
= true)]
public class CompareAttribute : ValidationAttribute
{
public string OriginalProperty { get; private set; }
public ValidationCompareOperator Operator { get; private set; }
public ValidationDataType Type{ get; private set; }

private const string _defaultErrorMessage = ‘{0}’ 与 ‘{1}’ 进行 {2} 比较失败;

public CompareAttribute(string originalProperty
, ValidationCompareOperator op, ValidationDataType type)
:
base(_defaultErrorMessage)
{
OriginalProperty
= originalProperty;
Operator
= op;
Type
= type;
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
name, OriginalProperty, Operator.ToString());
}

protected override ValidationResult IsValid(object value
, ValidationContext validationContext)
{
PropertyInfo originalProperty
= validationContext.ObjectType
.GetProperty(
this.OriginalProperty);
object originalValue = originalProperty.GetValue(validationContext.ObjectInstance, null);

if(!compare(value, originalValue))
return new ValidationResult(this.FormatErrorMessage(validationContext
.DisplayName));

return null;
}

private bool compare(object sourceProperty, object originalProperty)
{
int num = 0;
switch (this.Type)
{
case ValidationDataType.String:
num
= string.Compare((string)sourceProperty
, (
string)originalProperty, false, CultureInfo.CurrentCulture);
break;

case ValidationDataType.Integer:
num
= ((int)sourceProperty).CompareTo(originalProperty);
break;

case ValidationDataType.Double:
num
= ((double)sourceProperty).CompareTo(originalProperty);
break;

case ValidationDataType.Date:
num
= ((DateTime)sourceProperty).CompareTo(originalProperty);
break;

case ValidationDataType.Currency:
num
= ((decimal)sourceProperty).CompareTo(originalProperty);
break;
}
switch (this.Operator)
{
case ValidationCompareOperator.Equal:
return (num == 0);

case ValidationCompareOperator.NotEqual:
return (num != 0);

case ValidationCompareOperator.GreaterThan:
return (num > 0);

case ValidationCompareOperator.GreaterThanEqual:
return (num >= 0);

case ValidationCompareOperator.LessThan:
return (num < 0);

case ValidationCompareOperator.LessThanEqual:
return (num <= 0);
}
return true;

}
}

[转载]深入ASP.NET MVC3 Razor你准备好了吗?

mikel阅读(1140)

[转载]深入Razor,你准备好了吗?(兼谈我的学习方法和定位) – 撞破南墙 – 博客园.

目录

1 学习方法论

1下定义-针对不同的定义做不同的学习

2如何学习

3 知其所以然的学习

3MVC中页面引擎的入口

4我的定位

(主观的看法很多,说的不好不对的地方请多多指教)

1学习方法

给你要做的事下个定义

我的博士导师跟我说: 如果给问题下准了定义,那么问题就算解决了60%了。

来自《想外行一样思考,想内行一样实践》的一句话。

现在的问题便是你是如何看待razor,准备学习到什么样的程度?

先说说程度问题:

1了解阶段。

看看介绍(如news里面的文章)。知道有这么回事。

2 会用阶段。

那么仅仅是去看一些走马观花式的介绍性文章(比如我那个系列),基本就够你吹吹牛说你会用了。你也可以用在自己的小项目里。这时候你仅需要把所有的公开的API和属性,还有函数名弄懂是怎么回事就OK了。

3掌握应用阶段。

应用阶段不只要知道他是如何使用,更需要知道他的里面的代码是怎么跑的?

1知道里面的架构,知道他是怎么运作的(以便分析性能等)。

2知道他的使用范围和局限性,扩展性等。

我也说的不好,总结得不好,因为我正在这个阶段探索和努力。

4吸收为己用

1 或许是他的实现某个功能的一种机制。如mvvm都有的消息机制。

2 或许是其中的一些较好的写法和做法。比如我从OXITE(link)中学到了使用扩展方法来使得代码优雅,细粒度保持重用性,更好的泛型封装CURD等等。

3 或许是其中一些设计思想。比如一些设计模式,如何对一个大的架构进行解剖和隔离,我在这方面还没上路。

大家互相交流,我也是新手。

2读者类型和我自己的定位

好吧。我的朋友你是如何看待RAZOR的?

类型A:“无所不能”的技术至上的功能派:

如果你只是停留在第一第二阶段,不管你是否自己察觉。但对希望能够进入三,四层感觉,又不知道该如何下手。好吧,交个朋友!希望你能follow我的文章,让我们一起来经历一次这样的体验,真的很棒!

类型B:进阶型:

像我一样是一个脱离了功能派的有点自知之明了。但是又一直在想如何突破天花板,成为小牛。一直徘徊着的家伙们,这里有个同类。我觉得读代码的能力非常重要,对一个框架的深入探究和掌握也是一种非常好的锻炼。so follow me。

类型C:小牛大牛

没什么好说的,欢迎牛牛来指点!

3RAZOR是什么?

如你所知RAZOR是一个“剃须刀”,我这里是指MVC3 自带的页面引擎view  engine ,是指这一套类库。

4说了这么多,我们该如何学习呢?

具体的学法参考圣殿骑士的对框架的研究:

1,首先看框架的相关介绍,了解相关的背景、功能、架构图以及其他一些相关信息——认识了解。

2,根据介绍查看并调试框架所提供的实例——熟悉功能。

3,自己写一些相关的项目,主要是熟悉该框架,如果说要急于做项目,后面就可以把框架引入到项目当中——具体使用。

4,根据该框架提供的详细单元测试研究其源码,这也是我最喜欢研究这些开源框架的原因——原理剖析。

5,通过上面的步骤认真分析其原理及细节——准备重现。

6,自己也根据之前的思路重复开发这个框架,最好能用TDD——框架复原捷径。

更多的如何阅读代码,看这里

5 我自己的总结是这样。

1 是什么。

看介绍性的文章对其有一个基本的了解,知道他是干什么的。看其背景看其产生的原因,往往他产生的原因就是他的最初的核心功能也是最需要学习的。

2 使用它。使用该框架,看官方示例和一些入门系列,和文档来入门。如我们之前的一系列文章。

3了解全貌。有源码就看源码,知道其框架,分几部分,如何实现其核心功能,拆分各部分。心里有数。

4各个击破。拆成各部分后,一个模块一个模块的看。具体可以看接口,看基础类等,看其测试代码了解其要实现的功能。

5吸收。到了这个阶段,从整体到细节一切已经了然于胸,即使一些无聊的派生类等分支也有自信迅速看懂.我也没有什么经验。有的人把别人的框架里面的某些机 制变成自己永久代码类库的一部分( 我在积累),有的人以自己重新实现,甚至推出更优的同类的东西。这个看个人了吧。

下载MVC3的源码吧!不过。。。你真的准备好了吗?

http://aspnet.codeplex.com/wikipage?title=MVC&referringTitle=Home

3知其所以然的学习

既然说了这么多废话了,那就多说几句题外话吧。在开始找到MVC3中RAZOR页面引擎的入口前,我想先问一下看官,服务器接收到一个URL请求是如何处理又是在哪里返回给服务器的呢?

昨天看到 invoy给我留言,引起了我的思考。。。越反思,越冒汗。。最近在看的CLR VIA C#(LINK) 也说到了对代码的控制,失控是一件非常恐怖的事,如果你不知道你的代码干了什么,你将随着框架而摇摆,你懂的!

while(time++ &&  life– >0  ){
累;
}
die();

这里贴个图

2010112203014846

图片来自 HttpApplication处理管道

建议阅读:

Web开发学习心得5——Asp.net的设计思想 这篇写的通俗的,

———————–时光荏苒,转眼间你就懂得了一个URL如何传到了HttpApplication—————–

3MVC中页面引擎的入口

现在让我们进入MVC3中的源码,去解决我们第一个疑惑MVC3中是如何调用RAZOR这个页面引擎的。

STEP1

(参考重典大哥的文章http://www.cnblogs.com/chsword/archive/2010/07/10/1774937.html

我们找到几个关键的接口。通常从接口开始是个不错的选择。

IView :用于呈现

public interface IView {
void Render(ViewContext viewContext, TextWriter writer);
}

IViewEngine :用于找到页面

public interface IViewEngine {
ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache);
ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache);
void ReleaseView(ControllerContext controllerContext, IView view);
}

利用reflector工具顺藤摸瓜:

image

添加到类图

image

这下你应该清楚了

image

这下类的继承关系就很清楚了。也一目了然RAZOR和WEBFORM viewengine的关系。

STEP2

不去纠缠于细节,跳出来立马思考.我们虽然知道了他们继承于什么,

RAZOR在MVC3中的关系与位置立马清晰了,但是还是不知道到底是在哪里呈现。这时候有两个容易的思路。

第一个:是重典有提到过的一个

 ViewEngines.Engines.Clear();
 ViewEngines.Engines.Add(new WebPageEngine());

第二个:MVC在Controller 和 view 之间交互的时候。

我是想到了第一个,因为当时由他的文章启发去寻找,结果多费了些功夫。

如果你从第二个思路出发应该会更快。在这个地方我也花费了一点时间。

——时钟滴答—–

我发现了

public abstract class ActionResult {

public abstract void ExecuteResult(ControllerContext context);

}

image

现在整个思路终于串起来了。

public override void ExecuteResult(ControllerContext context) {
if (context == null) {
throw new ArgumentNullException(“context”);
}
if (String.IsNullOrEmpty(ViewName)) {
ViewName = context.RouteData.GetRequiredString(“action”);
}

ViewEngineResult result = null;

if (View == null) {
//1为 content 找到 页面并返回 ViewEngineResult
result = FindView(context);
View = result.View;
}

TextWriter writer = context.HttpContext.Response.Output;
//把所有的需要传递到view的东西都在这里
ViewContext viewContext = new ViewContext(context, View, ViewData, TempData, writer);
//在这里渲染页面
View.Render(viewContext, writer);

if (result != null) {
//发布结果
result.ViewEngine.ReleaseView(context, View);
}
}

1ActionResult 接收ControllerContext  并执行2和3

2IviewEngine负责找到页面

3 IVIEW 对应页面负责render呈现。

在这里就告一段落吧。一般都这里,我都是忍不住喜欢到处逛逛里面是

实现的,和更多的细节。

hi 我的朋友,你是否的朋友是否有所收获?

4我的定位

老赵 说:

希望可以给初学者以合适引导。坚定的北大青鸟反对者,强烈愤慨恶劣的培训机构对于处于懵懂期的初学者以误导,强烈抵制各种虚假广告给业界带来的不良影响,强烈建议有理想有抱负的从业青年放弃北大青鸟,不要做冤大头。

刘伟鹏 说:

知其所以然的学习。

好吧。我还是引用我之前写的一段话,表明我的立场。

[转载]GPS定位基本原理浅析

mikel阅读(1003)

[转载]GPS定位基本原理浅析 – Mobile On Line 镜像站点 – 博客园.

位置服务已经成为越来越热的一门技术,也将成为以后所有移动设备(智能手机、掌上电脑等)的标配。而定位导航技术中,目前精度最高、应用最广泛的,自然非GPS莫属了。网络上介绍GPS原理的专业资料很多,而本文试图从编程人员的角度出发,以一种程序员易于理解的方式来简单介绍一下GPS定位的基本原理,希望对做GPS开发的朋友有所启发。当然,本文并没有涉及具体的开发方面的技术。

一、GPS定位数学模型

之所以先介绍数学模型,是因为我认为这个数学模型可能是程序员比较关心的问题。当然事先声明,这个模型只是我根据一些GPS资料总专为程序员总结出来的一个简化模型,细节方面可能并不符合实际,想了解具体细节请参考专业的GPS讲解资料。

GPS定位,实际上就是通过四颗已知位置的卫星来确定GPS接收器的位置。

GPS_thumb22

如上图所示,图中的GPS接收器为当前要确定位置的设备,卫星1、2、3、4为本次定位要用到的四颗卫星:

  • Position1、Position2、Position3、Position4分别为四颗卫星的当前位置(空间坐标),已知
  • d1、d2、d3、d4分别为四颗卫星到要定位的GPS接收器的距离,已知
  • Location 为要定位的卫星接收器的位置,待求

那么定位的过程,简单来讲就是通过一个函数GetLocation(),从已知的[Position1,d1]、[Position2,d2]、[Position3,d3]、[Position4,d4]四对数据中求出Location的值。用程序员熟悉的函数调用来表示就是:

Location=GetLocation([Position1,d1],[Position2,d2],[Position3,d3],[Position4,d4]);

一看到这个函数调用,程序员们就该来劲了:这些参数从哪里来?这个函数又是如何执行?由谁来执行的呢?立体几何还没有忘干净的可能还要问:为什么必须要4对参数呢?那下面我们就来一起探究一下。

1.Position1、Position2、Position3、Position4这些位置信息从哪里来?

实际上,运行于宇宙空间的GPS卫星,每一个都在时刻不停地通过卫星信号向全世界广播自己的当前位置坐标信息。任何一个GPS接收器都可以通过天线很轻松地接收到这些信息,并且能够读懂这些信息(这其实也是每一个GPS芯片的核心功能之一)。这就是这些位置信息的来源。

2.d1、d2、d3、d4这些距离信息从哪里来?

我们已经知道每一个GPS卫星都在不辞辛劳地广播自己的位置,那么在发送位置信息的同时,也会附加上该数据包发出时的时间戳。GPS接收器收到数据包后,用当前时间(当前时间当然只能由GPS接收器自己来确定了)减去时间戳上的时间,就是数据包在空中传输所用的时间了。

知道了数据包在空中的传输时间,那么乘上他的传输速度,就是数据包在空中传输的距离,也就是该卫星到GPS接收器的距离了。数据包是通过无线电波传送的,那么理想速度就是光速c,把传播时间记为Ti的话,用公式表示就是:

di=c*Ti(i=1,2,3,4);

这就是di(i=1,2,3,4)的来源了。

3.GetLocation()函数是如何执行的?

这个函数是我为了说明问题而虚构的,事实上未必存在,但是一定存在这样类似的运算逻辑。这些运算逻辑可以由软件来实现,但是事实上可能大都是由硬件芯片来完成的(这可能也是每一个GPS芯片的核心功能之一)。

4.为什么要必须要四对参数?

根据立体几何知识,三维空间中,三对[Positioni,di]这样的数据就可以确定一个点了(实际上可能是两个,但我们可以通过逻辑判断舍去一 个),为什么这里需要四对呢?理想情况下,的确三对就够了,也就是说理想情况下只需要三颗卫星就可以实现GPS定位。但是事实上,必须要四颗。

因为根据上面的公式,di是通过c*Ti计算出来的,而我们知道c值是很大的(理想速度即光速),那么对于时间Ti而言,一个极小的误差都会被放大 很多倍从而导致整个结果无效。也就是说,在GPS定位中,对时间的精度要求是极高的。GPS卫星上是用銫原子钟来计时的,但是我们不可能为每一个GPS接 收器也配一个銫原子钟,因为一个銫原子钟的价格可能已经超过了这个GPS设备再加上使用GPS的这辆名贵汽车的价格。

同时,由于速度c也会受到空中电离层的影响,因此也会有误差;再者,GPS卫星广播的自己的位置也可能会有误差。其他等等一些因素也会影响数据的精确度。

总之,数据是存在误差的。这些误差可能导致定位精确度降低,也可能直接导致定位无效。GetLocation(函数)中多用了一组数据,正是为了来校正误差。至于具体的细节,我们就不用关心了,我们只要知道,多用一组数据,就可以通过一些巧妙的算法,消除或减小误差,保证定位有效。这就是GetLocation()函数必须用四组数据的原因,也就是为什么必须有四颗卫星才能定位的原因。

5.GetLocation()函数返回的位置信息怎样被GPS设备识别呢?

前面说在进行位置计算时都是用的空间坐标形式表示,但是对GPS设备及应用程序而言,通常需要用的是一个[经度,纬度,高度]这样的位置信息。那么 我们可以想象,在GetLocation()函数返回位置结果前,可能会进行一个从空间坐标形式到经纬度形式的转换,我们不妨假设存在一个 Convert(经纬度,空间坐标)这样的函数来进行这个转换。

6.单点定位与差分定位

实际上上面所说的只是定位原理中的其中一种,称为单点定位,或绝对定位。就是通过唯一的一个GPS接收器来确定位置。

GPS_thumb11

目前定位精度最高的是差分定位,或称相对定位。就是通过增加一个参考GPS接收器来提高定位精度。

GPS_thumb1

上面我们已经围绕一个虚拟的GetLocation()函数基本搞清楚了GPS定位的基本数学模型,对于编程而言,知道这些就足够了(其实不知道也不影响编程)。如果好奇心还没满足的话,我们继续了解一些GPS相关的背景知识。

二、GPS卫星是哪里来的?

(废话,当然是人发射的!地球人发射的!)

GPS(Global Position System,全球定位系统),全称为NAVSTAR GPS(NAVigation Satellite Timing And Ranging Global Position System,导航星测时与测距全球定位系统)。GPS是一个由美国国防部开发的空基全天侯导航系统,它用以满足军方在地面或近地空间内获取在一个通用参 照系中的位置、速度和时间信息的要求。

1.GPS发展历程

  • 1957年10月第一颗人造地球卫星SputnikⅠ发射成功,空基导航定位由此开始
  • 1958年开始设计NNSS-TRANSIT,即子午卫星系统;
    1964年该系统正式运行;
    1967年该系统解密以供民用。
  • 1973年,美国国防部批准研制GPS;
    1991年海湾战争中,GPS首次大规模用于实战;
    1994年,GPS全部建成投入使用;
    2000年,克林顿宣布,GPS取消实施SA(对民用GPS精度的一种人为限制策略)。

2.美国政府的的GPS策略

  • 两种GPS服务:
    SPS–标准定位服务,民用,精度约为100M;
    PPS–精密定位服务,军用和得到特许的民间用户使用,精度高达10M.
  • 两种限制民用定位精度的措施(保障国家利益不受侵害):
    SA–选择可用性,认为降低普通用户的测量精度,限制水平定位精度100M,垂直157M(已于2005年5月1日取消);
    AS–反电子欺骗。

3.其他卫星导航系统

  • GLONASS(全球轨道导航卫星系统),前苏联
  • Galileo-ENSS(欧洲导航卫星系统,即伽利略计划),欧盟
  • 北斗导航系统,中国

三、GPS系统的构成

GPS系统=空间部分+控制部分+用户部分

GPS_thumb23

1.空间部分

GPS空间部分主要由24颗GPS卫星构成,其中21颗工作卫星,3颗备用卫星。24颗卫星运行在6个轨道平面上,运行周期为12个小时。保证在任一时刻、任一地点高度角15度以上都能够观测到4颗以上的卫星。

主要作用:发送用于导航定位的卫星信号。

构成:24颗卫星=21颗工作卫星+3颗备用卫星

GPS_thumb1

2.控制部分

GPS控制部分由1个主控站,5个检测站和3个注入站组成。

组成:GPS控制部分=主控站(1个)+监测站(5个)+注入站(3个)

作用:监测和控制卫星运行,编算卫星星历(导航电文),保持系统时间。

  • 主控站:从各个监控站收集卫星数据,计算出卫星的星历和时钟修正参数等,并通过注入站注入卫星;向卫星发布指令,控制卫星,当卫星出现故障时,调度备用卫星。
  • 监控站:接收卫星信号,检测卫星运行状态,收集天气数据,并将这些信息传送给主控站。
  • 注入站:将主控站计算的卫星星历及时钟修正参数等注入卫星。

GPS_thumb3

分布情况:

  • 主控站:位于美国科罗拉多州(Calorado)的法尔孔(Falcon)空军基地。
  • 注入站:阿松森群岛(Ascendion),大西洋;迭戈加西亚(Diego Garcia),印度洋;卡瓦加兰(Kwajalein),东太平洋。
  • 监控站:1个与主控站在一起;3个与注入站在一起;另外一个在夏威夷(Hawaii),西太平洋。

GPS_thumb2

3.用户部分

GPS用户设备部分包含GPS接收器及相关设备。GPS接收器主要由GPS芯片构成。

如车载、船载GPS导航仪,内置GPS功能的移动设备,GPS测绘设备等都属于GPS用户设备。

组成:主要为GPS接收器

作用:接收、跟踪、变换和测量GPS信号的设备,GPS系统的消费者。

GPS定位是目前最为精确、应用最为广泛的定位导航技术,以后将会成为每一个移动设备的标配之一。现在的中高端只能手机,有相当一部分已经配备了 GPS硬件。那么针对GPS定位的开发技术也将成为一项主流常规技术。本文目的在于让准备进行GPS定位开发的编程人员对于GPS有一个大致的了解,这对 于编程可能没有什么直接的帮助,但是我想了解一下GPS的大致工作原理,在编程过程中就能够对GPS设备的工作特性有一个感性的认识,这对于开发还是有很 大间接好处的。想了解关于GPS定位的具体开发技术,请参考《为Windows Mobile设备创建位置感知的应用程序》

[转载]Windows Phone 7 开发书籍分享

mikel阅读(943)

[转载]Windows Phone 7 开发书籍分享 – {GnieTech} – 博客园.

我也来分享几本自己收藏的WP7 相关书籍,希望这几本书能对大家有所帮助~

第一本,《Programming Windows Phone 7》(完全版)Charles Petzold 的大作,园子里很多人发过不用过多介绍,必读书籍!

ProgWinPhone7

书籍下载(全彩)     源码下载

该书还有XNA Framework 和Silverlight 两种不同版本。

cat cat (1)

第二本,《Beginning Silverlight 3》 做WP7 开发Silverlight 是必须熟悉的,这本书是Silverlight 入门教材,适合从零开始。另,这本书目前已经有Silverlight 4 版本,但基于WP7 开发还是使用Silverlight 3 比较稳妥。

jAVpqIgE

书籍下载 源码下载

第三本,《Pro Silverlight 3 in C#》 如果您已经掌握了Silverlight 基本知识,那可以直接参考这本高级版本,该书同样有Silverlight 4 版本。

image_8

书籍下载(全彩)     源码下载

第四本,《Beginning Windows Phone 7 Development》 一本WP7 开发入门书籍,但书中并没有提及Silverlight 相关内容,直接从WP7 开发讲起,覆盖WP7 各个方面开发基础,并配合实例讲解WP7 应用开发技巧。

BeginningWindowsPhone7

书籍下载(全彩)     源码下载

第五本,《Professional Windows Phone 7 Application Development》 本书是WP7 应用专业开发书籍,详细介绍如何使用Visual Studio、Silverlight 和XNA 框架开发WP7 应用、游戏等。(这本书600多页,居然有186MB)

cover

书籍下载 源码下载

最后一本,《Beginning XNA 3.0 Game Programming: From Novice to Professional》 如果要做WP7 的游戏开发,可以通过这本书了解一下XNA 开发相关知识。

198-9

书籍下载 源码下载

[转载]关系型数据库性能优化总结

mikel阅读(806)

[转载]关系型数据库性能优化总结 – Xiaojun Liu’s Blog – 博客园.

对于web应用开发,多数性能瓶颈均出现在数据库上,除了采用分布式架构或云处理(大公司基本上都是),更重要的是平时程序设计时要遵照一些规则,从根本上提高系统的性能,以下总结了一些常用的规则方法,仅供参考,欢迎跟帖补充。。。

1、 把数据、日志、索引放到不同的I/O设备上,增加读取速度。数据量(尺寸)越大,提高I/O越重要。

2、 纵向、横向分割表,减少表的尺寸,如:可以把大数据量的字段拆分表。

3、 根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。注意填充因子要适当(最好是使用默认值0)。索引应该尽量小,尽量使用字节数小的列建索引,不要对有限的几个值的列建单一索引。

4、 OR的字句可以分解成多个查询,并且通过UNION链接多个查询。它们的速度只与是否使用索引有关,如果查询需要用到联合索引,用UNION all执行的效率更高。

5、 在查询SELECT语句中用WHERE子句限制返回的行数,避免表扫描。如果返回不必要的数据,则浪费了服务器的I/O资源,加重了网络的负担,降低了性能。如果表很大,在表扫描期间将表锁住,禁止其他的联结访问表,后果很严重。

6、 注意使用DISTINCT,在没有必要时不要用,它同UNION一样会使查询变慢。

7、 IN后面值的列表中,将出现最频繁的值放在最前面,出现最少的放在最后面,减少判断的次数。

8、 一般在GROUP BYHAVING子句之前就能剔除多余的行,所以尽量不要用它们来做剔除行的工作,也就是说尽可能在WHERE中过滤数据。

9、 尽量将数据的处理工作放在服务器上,减少网络的开销,如使用存储过程。存储过程是编译、优化过,并且被组织到一个执行规划里,且存储在数据库中的SQL语句(存储过程是数据库服务器端的一段程序),是控制流语言的集合,速度当然快。

10、 不要在一句话里再三地使用相同的函数,浪费资源,将结果放在变量里再调用更快。

11、 针对大量只读查询操作进行优化的方法:

1) 数据量小的数据,可以考虑不存储在数据库中,而是通过程序常量的方式解决。

2) 需要存储在数据库中的数据,可以考虑采用物化视图(索引视图)。当DBA在视图上创建索引时,这个视图就被物化(执行)了,并且结果集被永久地保存在唯一索引中,保存方式与一个有聚簇索引的表的保存方式相同。物化视图减除了为引用视图的查询动态建立结果集的开销,优化人员可以在查询中使用视图索引,而不需要在FROM子句中直接指定视图。

3) 数据存储时可以考虑适当的数据冗余,以减少数据库表之间的链接操作,提高查询效率。

4) 针对数据的特点,采取特定的索引类型。例如,位图索引等。

12、 对于SQL语句书写时的一些建议:

1) 写语句时能够确定数据库对象所有者的,尽可能把所有者带上,如:

SELECT * FROM dbo.Users

2) 存储过程中,参数定义最好放在最前面,尽可能一次定义,如:

DECLARE @USER_ID INT

,@USER_NAME   VARCHAR(50)

,@PASSWORD VARCHAR(50)

3) 为参数赋值时,尽可能一次赋值,如:

SELECT @USER_ID = 1001

,@USER_NAME = ‘xiaojun.liu’

4) 尽量少用游标

13、 。。。。。。

[转载]ASP.Net MVC不想在多个Action上写同样的FitlerAttribute(上)

mikel阅读(999)

[转载]ASP.Net MVC探索之路 – 不想在多个Action上写同样的FitlerAttribute(上) – Catcher In The Rye – 博客园.

以AuthorizeAttribute这个Filter举例,一个Controller有若干个Action,包括登录的Action(如 Login)。这时我们就不能将Authorize放在Controller签名之上,不得不给除了Login这个Action之外的所有Action加 上个Authorize——这也不是大不了的事情,我多写几个Authorize也觉得没关系,或者我重新实现一个 IAuthorizationFilter,在里面判断如果是Login这个Action,就不进行验证。

如果我想给所有Action注入一段html到页面底部,我必须去修改Controller吗?
如果我想动态控制某个Action允许由哪些角色访问,我通过修改Controller能实现吗?
如果我想这时候控制的由哪些角色来访问,需求改变时我想要控制由哪些用户来访问呢?我还得去修改Controller吗?或者增加或修改Filter吗?

所以需求就出现了:能不能让我集中管理这些Filter,并且控制的更灵活呢?能让所有Controller和Action签名上都干干净净的那就最好了。

那就把Filter放在一处集中管理,在Action或ActionResult等执行Filter之前保证将需要的Filter准备好就行了。

在解决问题之前,先简单回顾一下Action执行前后发生的事。

我们知道,在ASP.NET MVC中,每一次请求通常都定位到一个具体的Controller的Action中。
在默认情况下,由Action执行器ControllerActionInvoker类去控制Action的执行(或不执行),实际做事的是InvokeAction方法。
InvokeAction 方法首先去查找Action(由FindAction方法),如果Action被找到了,会去检索该Action拥有的Filter以及该Action所 属Controller的Filter(由GetFilters方法),将找到的所有Filter放入一个FilterInfo变量 中,FilterInfo中保存的Filter不完全是Action是自己的。然后先执行找到的所有IAuthorizationFilter(由 InvokeAuthorizationFilters方法)。当然,在InvokeAuthorizationFilters方法中,只要有 IAuthorizationFilter的ActionResult不为null就会返回不会执行其他的了。 InvokeAction方法检测执行结果,如果ActionResult的确不为空,则执行该Result,其他Filter就不管啦。 接着获取要传给Action的参数集(交给GetParameterValue方法),就执行 InvokeActionMethodWithFilters方法,方法名已经足够说明它是干什么的了。如果一切正常,根据 InvokeActionMethodWithFilters方法返回的结果去接着就执行InvokeActionResultWithFilters方 法。在执行InvokeAuthorizationFilters一直到执行InvokeActionResultWithFilters的这一整个过程 中如果发生异常,则根据捕获的异常执行InvokeExceptionFilters进行异常处理。

这里需要注意一 点:InvokeAction、GetFilters、InvokeAuthorizationFilters、GetParameterValue、 InvokeActionMethodWithFilters、InvokeActionResultWithFilters、 InvokeExceptionFilters等全是虚方法,除非有足够的原因去继承IActionInvoker重写一个Action执行器,否则重写 某些方法足够扩展。

甚至ControllerActionInvoker类本身,在ASP.NET MVC基础架构中也是可以替换的,怎么替换呢?继承Controller类时重写CreateActionInvoker方法就可以。

另 外还可以在构造Controller对象给它的ActionInvoker属性赋值,这又怎么赋值?重写 DefaultControllerFactory创建Controller实例的GetControllerInstance方法。 然后在Applicaion_Start中设置新的ControllerFactor:
ControllerBuilder.Current.SetControllerFactory(new YourControllerFactory());

回到主题。 首先我们将Filter和Action的对应关系(Filter和Controller的对应关系在本文中暂不讨论)存于一个集合中并缓存起来。

从 找到Action到执行InvokeAuthorizationFilters之前,必须将IAuthorizationFilter准备好;从找到 Action到执行InvokeActionMethodWithFilters之前,必须将Action需要的IActionFilter准备好;从找 到Action到执行InvokeActionResultWithFilters之前,必须将ActionResult需要的 IResultFilter准备好。异常发生InvokeExceptionFilters执行之前,必须将IExceptionFilter准备好。 基于以上几点,我们好像只能在FindAction方法和GetFilters方法之间选择一个。当然也就是只有GetFilters了。

在Filter方法中,我们根据当前Action的特征(如方法名,或包括请求方式Get或Post)与Filter和Action对应表。将匹配的Filter加进FilterInfo变量中。

下一章讨论一下具体的实现。感兴趣的可以去看看Oxite ,它实现了本章提到的一部分的需求。

[转载]JavaScriptMVC 3.0 发布

mikel阅读(1021)

[转载]JavaScriptMVC 3.0 发布 – Java编程 – JavaEye新闻.

JavaScriptMVC 是一个功能强大的JavaScript framework,也是一个很棒的JavaScript测试框架。JavaScriptMVC 应用了模型-视图-控制器架构模式,把业务逻辑和表示分离,使得代码更加模块化。通过它可以简化项目的开发,支持流行的各种浏览器。

距JavaScriptMVC 2.0版本发布一个多月,JavaScriptMVC团队今天发布了 3.0 版本。该版本增加了一些 2.0 版本以外的新功能,更主要的是完善了现有的一些功能。

JavaScriptMVC 3.0的新功能包括:

FuncUnit – Web 测试框架

Stand Alone Sub Projects
– You can download only the tools you need

Multi-Page builds – Optimize builds across multiple pages

Less and CoffeeScript support – Use Less and CoffeeScript without having to refresh your page.

New Folder Structure – A revamped file structure that makes it easier to build modular applications.

Learn-ability – Much better docs, examples, demo, etc.


点击JavaScriptMVC 3.0 版本其他详细信息请查看:http://jupiterjs.com/news/javascriptmvc-3-0-good-to-go

下载JavaScriptMVC 3.0:http://code.google.com/p/javascriptmvc/downloads/list

[转载]ASP.NET MVC3-Razor-给力的调试和预加载

mikel阅读(1175)

[转载]MVC3-Razor-给力的调试和预加载 – 撞破南墙 – 博客园.

1在RAZOR中调试

如你所知,对于发布后的网站,调试往往是一件非常悲剧的事。

看看RAZOR中强大的打印功能

@ObjectInfo.Print(this.Context.User)

  • image

2获取服务器信息

@ServerInfo.GetHtml()

image

image

3FormsAuthentication.SlidingExpiration 属性

取得值,指出是否启用滑动期限。

SlidingExpiration 属性值通过使用 forms 配置元素的 slidingExpiration 特性进行设置。

如 果发出了请求并且超时间隔过半,则可调过期功能将重新设置有效的身份验证 Cookie 的到期时间。 如果 Cookie 到期,用户必须重新进行身份验证。 如果将 SlidingExpiration 属性设置为 false,则可使身份验证 Cookie 的有效时间受限于所配置的 timeout 值,从而提高应用程序的安全。

如果将 requireSSL 配置为 false,则建议将 slidingExpiration 也配置为 false,从而缩短票证的有效时间。

4 预加载

3.1首次进入程序后首先执行根目录下的_AppStart.cshtml

(如果3.1我们自己也能在code里硬编码写一个的话,3.2的功能就更赞了!)

3.2每次进入文件夹首先执行文件夹下的_ViewStart.cshtml

image

假设我们首次访问  cahe下的 index.cshtml 页面,会按照如上所示的图示来执行。

但如果不是首次访问1会被跳过。而每次进入cahe下的文件都会执行3中的_ViewStart.cshtml

这就给了我们很多时候的操作提供了非常多的方便。

比如在 1中 就可以设置全局缓存和变量,比如在线人数统计,

版权信息,邮箱的设置等等。

而在二中,我们单独为特定文件夹下的页面设置访问权限或者主题等等。

[转载]SharePoint 2010使用Correlation ID快速查找错误信息

mikel阅读(1137)

[转载][SharePoint 2010]使用Correlation ID快速查找错误信息 – 致良知,知行如一 – 博客园.

不管是作为一名开发人员还是IT管理人员在与 SharePoint朝夕相处的日子里,最头疼的工作可能就要算是Trouble Shooting了,不论代码写的多么的好,整体架构设计的多么完善,错误总是难以避免的。在SP 2010中微软在错误信息以及日志上带给我们许多新的功能,各人认为其中最吸引人的功能就要算是当页面抛出错误信息时所获得的这个Correlation ID了,有了它我们就可以很快速和方便的定位到SharePoint日志中的错误信息了,在Trouble Shooting时,找到正确的错误信息,是顺利解决问题的第一步,也是关键性的一步。下面我将为各位看官介绍一下怎样使用Correlation ID查找错误信息。

什么是Correlation ID呢?

在SharePoint 2010中Correlation ID就是一串GUID,在发生错误的时候可以通过它在日志中查找到该错误的详细信息。

在SP 2010里,每一个request都会有一个Correlation ID,所以如果在一个request进程中出现错误的话,使用Correlation ID来查找错误信息是最好的方法。

先来看一个SP 2010里的错误信息画面,不知道各位是不是都见到过这种错误信息画面,如果还没见过,相信我,你会见到的。微笑

通过Correlation ID搜索错误信息

假设现在我们的SharePoint站点抛出了一个错误,然后我们想查看这个错误的具体信息,最笨的方法当然就是去日志中一条条的找了,但这显然不符合这篇文章的标题,那么应该怎么做呢?下面这两种方法就将帮助我们快速的定位错误信息。

使用PowerShell通过Correlation ID在SharePoint日志中查找详细的错误信息

一个最简单与快速的方法就是通过PowerShell命令来完成这项工作。在SP 2010中已经可以使用PowerShell来管理我们的SharePoint了,通过下面这条命令就可以通过Correlation ID获得具体的错误信息了。(将GUID替换成报错画面中的GUID)

get-splogevent | ?{$_Correlation -eq “<GUID>” }

这条命令会显示我们所要查找的错误的详细信息,就像下面这张图一样。

1207_02

现在这些信息还是有些多,有一些作用不是很大的信息我们并不关注,例如EventID、Level等等,这时我们可以试试下面这条命令。

get-splogevent | ?{$_.Correlation -eq “<GUID>”} | select Area, Category, Level, EventID, Message | Format-List

这条命令会带给我们一个更加友好的详细错误信息画面。

1207_03

最后,假如想把这条信息保存下来,则只需要在上面那条命令的结尾处加上“> C:\Error.log”这条命令就行了。

get-splogevent | ?{$_.Correlation -eq “<GUID>”} | select Area, Category, Level, EventID, Message | Format-List > C:\Error.log

1207_04

在数据库中通过Correlation ID查找错误信息

除了使用PowerShell命令来查找错误信息以外,另外一个比较简单的方法是直接在数据库中查找你所需要的错误信息。在日志数据库中,一般叫做WSS_Logging,在这个数据库中有一个名为ULSTraceLog的视图,在这个视图里可以查找到详细的错误信息。

select 	[RowCreatedTime],  [ProcessName],  [Area],
 		[Category],  EventID,  [Message]
 from  [WSS_UsageApplication].[dbo].[ULSTraceLog]
 where  CorrelationId=< pre>'B4BBAC41-27C7-4B3A-AE33-4192B6C1E2C5'
例如,我们可以使用上面这条SQL语句来查找CorrelationID为'B4BBAC41-27C7-4B3A-AE33-4192B6C1E2C5'的错误信息。
1207_05
使用CorrelationID我们可以轻松的跟踪SP 2010中的错误,这无疑将大大的减少我们的工作难度,只需记下CorrelationID,我们就可以

[转载]iPhone新开发Apple Store上软件的实施步骤

mikel阅读(923)

[转载]新开发Apple Store上软件的实施步骤 – Thinker – 博客园.

最近需要做一个在iPhone上发布的小软件,由于是新手,发现网上的资料比较零散,通过整个的过程走一遍,总算顺利的把开发环境和相关的流程搞清楚了。

开发者计划

如果想用 XCode 在 iPhone 上联机调试代码,那就要先注册成为苹果开发者,再加入苹果的 iOS 开发者计划。

以 Individual 名义和 Company 名义加入苹果开发者计划的不同之处是,前者需要给苹果传真身份证扫描件,后者需要给苹果传真营业执照 扫描件。这里选择以 Company 名义加入苹果开发者计划。苹果公司会对每个开发者收取99美元或299美元的年费

个人注册的步骤: http://www.cnmsdn.com/html/201010/1287498482ID8474.html

企业注册的详细步骤: http://www.cnblogs.com/scottwong/archive/2010/12/05/1896770.html

如何购买软件

http://zhidao.baidu.com/question/154145910.html

机器上安装ITunes【store.apple.com上的课购买内容很少】,然后注册一个Apple ID,设置信用卡号码,正确设置后会预付1美元【是退回的,不是真支付】,然后就可以购买了。

【App Store基础知识】我的1美元哪去

http://bbs.weiphone.com/read-htm-tid-1278721.html

如何使用(国内)信用卡购买appstore的软件

http://zhidao.baidu.com/question/142745315.html

苹果 Mac App Store 软件审查准则公开!

http://cn.engadget.com/2010/10/22/apples-mac-app-store-review-guidelines-posted-will-photoshop/ http://www.cocoachina.com/bbs/read.php?tid-31964.html

开发环境建立

由于没有Mac电脑,因此购买了一个Mac Mini作为基础的开发和测试环境,成本也比较低

【虽然使用网上的一些推荐方法在PC上也可安装Mac OS系统,但速度和效率都比较慢】

http://developer.apple.com 下载SDK和开发工具,安装即可进行软件的开发和调试了

参考网址

http://developer.apple.com

http://store.apple.com/

http://store.apple.com/cn

http://www.cocoachina.com/

http://www.weiphone.com/ 其中的BBS有很多的资源