1.[Required] : 必须输入
[Required(ErrorMessage = "请输入用户名")]
2.[StringLength] : 限制字符串长度
[StringLength(10, ErrorMessage = "长度不能超过10个字符")]
3.[Range] : 限制取值范围
[Range(0, 120, ErrorMessage = "年龄范围在0到120岁之间")]
4.[RegularExpression] : 必须符合某个正则表达式(1)直接使用RegularExpression来写表达式:
01.[RegularExpression(@"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "请输入Email格式")]
02.public String RegualarExpressionField { get; set; }
介绍一些在开发中非常有用的MVC特性,如下:
BindAttribute
Remote
HandleError
HiddenInput
1.BindAttribute
使用BindAttribute的目的是限制用户在提交form表单时使用合适且正确的值。当我们提交一个表单时,就会检查每一个实体上绑定的特性。
假设我们已经有下面一个Employee实体类:
public class Employee
{
public string Name { get; set; }
public string Email { get; set; }
public string Address { get; set; }
public string PhoneNo { get; set; }
}
现在如果我们只想提交Email,Name和PhoneNo,而我们不想提交地址,这时我们可以在实体类上添加如下特性:
[Bind(Exclude="Address")]
public class Employee
{
public string Name { get; set; }
public string Email { get; set; }
public string Address { get; set; }
public string PhoneNo { get; set; }
}
BindAttribute要在System.Web.Mvc命名空间下使用,使用BindAttribute,我们可以在提交表单时对字段进行一些控制。在下面的图中,我们已经在提交的form数据中得不到Address的值了。
我们也可以将BindAttribute直接用在Action的参数中,像下面这样:
public Actionresult emprigister([Bind(Exclude="Address")],Emploree emp)
{
}
2.RemoteAttribute
假设我们有一个注册表单,里面有邮箱文本框,当输入邮箱后,我们想检查输入的邮箱是否在数据库中已经存在,如果存在,则不提交表单,这时我们可以使用RemoteAttribute,通过RemoteAttribute,我们可以在不用提交表单就可以先进行一些服务端验证。
我们可以在下面的例子中使用RemoteAttribute:
public class Employee
{
public string Name { get; set; }
[Remote("CheckEmail","Employee",ErrorMessage="Email is already exist")]
public string Email { get; set; }
public string Address { get; set; }
public string PhoneNo { get; set; }
}
RemoteAttribute的第一个参数是一个Action名字,第二个是Controller名字,第三个是如果邮箱已存在后显示给用户看的提示信息。当我们输入完邮箱后,CheckEmail方法将被执行并检查邮箱是否存在。
public JsonResult CheckEmail(string Email)
{
//Check here in database if it exist in database return true else false.
return Json(false, JsonRequestBehavior.AllowGet);
}
3.HandleError Attribute
我们已经有很多方法在MVC中处理异常,比如用try catch,或者使用Filter,或者通过第三方库比如elmah。但是MVC也提供了一个HandleErrorAttribute去处理异常,如下:
[HandleError()]
public ActionResult CheckError()
{
int a = 10;
int b = 0;
int k = a / b;
return View();
}
在web.config文件中,我们添加如下两行:
<customErrors mode ="On" defaultRedirect ="Error.cshtml">
</customErrors>
在shared文件夹下创建一个视图Error.cshtml,然后运行程序,如果运行上面的CheckError()方法,你刚创建的Error.cshtml将会显示出来。
我们也可以使用HandleErrorAttribute给不同类型的异常显示不同的视图页面。
[HandleError(ExceptionType=typeof(DivideByZeroException),View="DivideByZeroErrorView")]
[HandleError(ExceptionType = typeof(NullReferenceException), View = "NullRefrenceErrorView")]
public ActionResult CheckError()
{
int a = 10;
int b = 0;
int k = a / b;
return View();
}
4.HiddenInput Attribute
如果我们想对用户隐藏一些实体字段,我们可以使用HiddenInput特性。
public class Employee
{
[HiddenInput(DisplayValue=false)]
public string Name { get; set; }
[Remote("CheckEmail","Employee",ErrorMessage="Email is already exist")]
public string Email { get; set; }
public string Address { get; set; }
public string PhoneNo { get; set; }
}
在以上的实体中,我用HiddenInput特性去描述Name字段。这样程序运行后在浏览器中Name字段将不在显示。因此HiddenInput给我们d 在实体字段上多了一些额外的控制。
boootstrap talbe多列checkbox设置
boootstrap talbe 列值进行格式化操作:
{
title: '审核',
field: '审核',
// width: '10%',
// align: "left",
formatter: function (value, item, index,row) {
if (value == '1') {
return '<input type="checkbox" id="a_' + index + '" checked = "checked"/>';
}
else if (value == '0') {
return '<input type="checkbox" id="a_' + index + '" />';
}
else if (value == null) {
return '<input type="checkbox" id="a_' + index + '" />';
}
}
}
//***************************************************8
2. 在table的cell单击事件里取值赋值
onClickCell:function(field, value, row, $element,index)
{
// alert("单击cell-" + value);
// alert("单击cell-" + row.id);
// if ($('#a_' + index).get(0).checked) {
if ($('#a_' + index).is(':checked')) {
row.审核 = "1";
} else {
row.审核 = "0";
}
alert(value+"单击cell-" + row.id);
},
抽象类与接口紧密相关。然接口又比抽象类更抽象,这主要体现在它们的差别上:1)类可以实现无限个接口,但仅能从一个抽象(或任何其他类型)类继承,从抽象类派生的类仍可实现接口,从而得出接口是用来解决多重继承问题的。2)抽象类当中可以存在非抽象的方法,可接口不能且它里面的方法只是一个声明必须用public来修饰没有具体实现的方法。3)抽象类中的成员变量可以被不同的修饰符来修饰,可接口中的成员变量默认的都是静态常量(static final)。4)这一点也是最重要的一点本质的一点"抽象类是对象的抽象,然接口是一种行为规范"。
以上是它们本身的异同,下面再来从实际应用讲讲它们的异同!
不同之处:
1、定义
抽象类表示该类中可能已经有一些方法的具体定义,但是接口就仅仅只能定义各个方法的界面(方法名,参数列表,返回类型),并不关心具体细节。
1、用法
1)在继承抽象类时,必须覆盖该类中的每一个抽象方法,而每个已实现的方法必须和抽象类中指定的方法一样,接收相同数目和类型的参数,具有同样的返回值,这一点与接口相同。
2)当父类已有实际功能的方法时,该方法在子类中可以不必实现,直接引用的方法,子类也可以重写该父类的方法(继承的概念)。
3)而实现 (implement)一个接口(interface)的时候,是一定要实现接口中所定义的所有方法,而不可遗漏任何一个。
4)另外,抽象类不能产生对象的,但可以由它的实现类来声明对象。
有鉴于此,在实现接口时,我们也常写一个抽象类,来实现接口中的某些子类所需的通用方法
对于C#初学者来说,abstract抽象类在网上的定义和解释说了一大堆,却往往我们忽视了为何要使用abstract类,使用它的意义在哪里。面试的时候也会有人问起使用它有什么好处,因为不适用它用自己定义的类也可以实现。那么为什么要使用抽象类?
那么我们什么时候应该用抽象类呢?
如果一个类设计的目点是用来被其它类继承的,它代表一类对象的所具有的公共属性或方法,那个这个类就应该设置为抽象类。
抽象类与其它的类有什么区别呢?
抽象类是不能够被实例化的。如果一个类中包含有抽象方法,那么这个类一定要声明为抽象类。同时,抽象方法一定需要在子类中重写,让抽象方法成为一个具体的实实在在的方法。
相信大家在网上一定看过很多这类解释了吧?好吧,不理解的我们一起来看看通俗易理解的说法吧:
比如说:我们需要创建 “狗”、“猫”、“鱼”、“马”这些对象(类),我们可以说他们有一些共同的属性像嘴巴、尾巴、重量、颜色、大小等等一些共同的属性(properties),但是它们彼此的属性的形状是不同的(如嘴巴),在这种情况下,我们如果一个个去定义各自类似的属性是不是比较繁琐?如果用抽象类是不是很方便的给他们去继承。抽象类也有个更加好的地方,体现在“同质异像”就是实质相同实现形式不同的方法继承上,例如上面的狗、猫、马等的呼吸这个方法或者跑的速度的方法形式不同,我们这个是用定义一个抽象方法,让他们各自的类去实现它是不是很方便。“抽象”的意义正在于此。将共同的东西抽出来封装,但不实现只给继承。
c#为什么要使用接口?通俗的讲,就是为了降低耦合度。给大家看一个我见过的很搞笑的例子。看看下面的程序:一个学校里边,有两种人:学生、老师。他们都要吃饭和睡觉。------------------------------public interface I人{ void 吃饭(); void 睡觉();}public class 学生:I人{ public void 吃饭() { //去食堂吃饭 } public void 睡觉() { //回寝室睡觉 } //其他特有方法,比如泡妞、打游戏}public class 老师:I人{ public void 吃饭() { //回家吃饭 } public void 睡觉() { //回家睡觉 } //其它特有方法,比如为生儿育女传宗接代的历史使命努力等“不足为外人道也”的事情}public class 学校{ public void 开饭(I人 ren) { ren.吃饭(); } public void 放学(I人 ren) { ren.睡觉(); }}----------------------------- 这里就用到了里氏代换原则,"开饭()"和"放学()"的参数都是人,那么这个地方如果换成学生和老师肯定也可以。I人 某学生 = new 学生();某学生.开饭();某学生.放学();这样执行的结果就是学生回寝室吃饭。I人 某老师 = new 老师();某老师.开饭();某老师.放学();这样执行的结果就是老师回家吃饭。 为什么要这样写呢?这样写有什么好处呢? 我在开饭的时候完全可以直接调用“学生.吃饭();”、“老师.吃饭();”。接着看,有一天,学校里来了第三种人,家长。 家长既不是去寝室睡觉也不是回家睡觉,而是旅馆睡觉,既不是去食堂吃饭也不是回家吃饭,而是去下馆子。 这个时候学校这个系统该怎么处理呢? 如果原来没有定义"I人"这个接口那就麻烦啦,所有用到人的地方代码都要改。 现在不一样了,我可以直接定义一个类:家长,这个类实现人这个接口就可以了。 好,看代码:------------------------------public class 家长:I人{ public void 吃饭() { //下馆子 } public void 睡觉() { //去旅馆睡觉 } //其它特有方法,比如会见老师,晓之以钱,动之以利等等,不一而足}------------------------------- 在调用的时候不需要修改任何代码,还和原来一样:I人 某家长=new 家长();某家长.开饭();某家长.放学(); 轻松搞定家长的食宿问题! 这样一来学校来再多的客人都没关系啊,绝对可以应付自如,这也就是传说中的可扩展性!不知道大家看到这里是不是能够明白接口的作用。如果你还不明白,那么你把人这个接口去掉,自己写一个学校开饭和放学的类,然后再加一个家长这个新新人类进去,看看你的代码是什么样子的,再想一下在人口这么多的中国,万一哪天你的学校里来了成千上万个新新人类你该怎么办! 先声明一下,这个案例可不是我想出来的~~但是很经典,是不? 然后我们就很好理解了,为什么用别人的东西要实现接口呢?很直接的一个原因是这样一来,编程的复杂度就可能会大大降低了,不是么?
calc 是 css3提供的一个在css文件中计算值的函数:
用于动态计算长度值。
需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px);
任何长度值都可以使用calc()函数进行计算;
calc()函数支持 "+", "-", "*", "/" 运算;
calc()函数使用标准的数学运算优先级规则;
calc(100vh - 10px) 表示整个浏览器窗口高度减去10px的大小 calc(100vw - 10px) 表示整个浏览器窗口宽度减去10px的大小 一般用来设置流式布局宽高,当然,你可以使用calc()给元素的border、margin、pading、font-size和width等属性设置动态值 calc()的兼容性如下,使用时需注意
在讲calc之前先说一下 vh vw:
vw 相对于视口的宽度。视口被均分为100单位的vw
vh 相对于视口的高度。视口被均分为100单位的vh
vmax 相对于视口的宽度或高度中较大的那个。其中最大的那个被均分为100单位的vmax
vmin 相对于视口的宽度或高度中较小的那个。其中最小的那个被均分为100单位的vmin
$('#grid').datagrid({
columns:[[
{field:'CODE_NM',title:'名称',align:'center',width:'40%'},
{field:'a',title:'选项A',width:'15%',align:'center',
formatter: function (value, rowData, rowIndex) {
if(value=="1"){
return '<input type="checkbox" id="a_'+rowIndex+'" />';
}else if(value="0"){
return '<input type="checkbox" id="a_'+rowIndex+'" checked = "checked"/>';
}
}},
{field:'b',title:'选项B',width:'15%',align:'center',
formatter: function (value, rowData, rowIndex) {
if(value=="1"){
return '<input type="checkbox" id="b_'+rowIndex+'" />';
}else if(value=="0"){
return '<input type="checkbox" id="b_'+rowIndex+'" checked="checked"/>';
}
}}
]],
width:'100%',
hight:'100%',
rownumbers:true,
title:'列表信息',
url:"getDetail",
onClickRow:function(index,row){
$('#grid').datagrid('clearSelections');
if($('#a_'+index).get(0).checked){
row.a = "0";
}else{
row.a = "1";
}
if($('#b_'+index).get(0).checked){
row.b = "0";
}else{
row.b = "1";
}
},
dataType:"json",
type:'post',
onLoadSuccess:function(data){
}
});
前言:作为.Net攻城狮,你面试过程中是否遇到过这样的问题呢:什么是事件?事件和委托的区别?既然事件作为一种特殊的委托,那么它的优势如何体现?诸如此类…你是否也曾经被问到过?你又是否都答出来了呢?
关于面试中涉及到的事件的问题,我们只需要抓住几个关键点就好了:
(1)事件是委托的封装,可以理解为一种特殊的委托。
(2)事件里面其实就两个方法(即add_event()和remove_event())和一个私有的委托变量,这两个方法里面分别是对这个私有的委托变量进行的合并和移除,当调用事件的+=时其实是调用的事件里面的add_event()方法,同样-=调用的是remove_event()方法。
(3)事件只能够从对象外部增加新的响应方法和删除已知的响应方法,而不能主动去触发事件和获取其他注册的响应方法等信息。如果使用公有的delegate则不能做这些限制,也就是说事件对委托做了限制,使委托使用起来更加方便。也有人说事件是对委托的阉割,大概也是这个意思。
如果回答的时候抓住了以上的3点,那么我想你的面试应该不会太差。毕竟面试那么短的时间,有一两个亮点就很不错了,你说呢。哪怕你对事件机制完全不懂,为了面试记住其中两点也是很好的,工作经验咱们没有,换工作的经验可不能没有哦~~扯远了,关于面试就到此为止。如果你还想继续将事件了解透彻,别着急,慢慢往下看。
1、事件的定义及由来:
定义事件:
public delegate void MyStudyEvent(
object sender, EventArgs e);
public class TestEvent
{
public event MyStudyEvent eMyStudyEvent;
}
将这段代码生成dll后,通过反编译工具reflector我们可以看到:
c# 基础事件
正如上文所说,可以看到当定义一个事件public
event MyStudyEvent eMyStudyEvent的时候,编译器会自动给他生成两个方法add和remove,以及一个private的委托变量eMyStudyEvent。我们将反编译代码copy出来看看。
可以看到这两个方法的主要作用就是在向private变量eMyStudyEvent里面添加委托和移除委托。当调用事件的+=和-=时,eMyStudyEvent里面就合并和移除传过来的委托,当事件触发的时候,eMyStudyEvent变量就执行。这样设计也正好符合封装的原则,保证了内部变量的安全性。
//私有委托变量
private MyStudyEvent eMyStudyEvent;
//add方法合并委托到eMyStudyEvent里面
public void add_eMyStudyEvent(MyStudyEvent value)
{
MyStudyEvent event3;
MyStudyEvent eMyStudyEvent = this.eMyStudyEvent;
do
{
event3 = eMyStudyEvent;
MyStudyEvent event4 = (MyStudyEvent)System.Delegate.Combine(event3, value);
eMyStudyEvent = Interlocked.CompareExchange<MyStudyEvent>(ref this.eMyStudyEvent, event4, event3)
}
while (eMyStudyEvent != event3);
}
//remove方法移除eMyStudyEvent里面已存在的委托
public void remove_eMyStudyEvent(MyStudyEvent value)
{
MyStudyEvent event3;
MyStudyEvent eMyStudyEvent = this.eMyStudyEvent;
do
{
event3 = eMyStudyEvent;
MyStudyEvent event4 = (MyStudyEvent)System.Delegate.Remove(event3, value);
eMyStudyEvent = Interlocked.CompareExchange<MyStudyEvent>(ref this.eMyStudyEvent, event4, event3);
}
while (eMyStudyEvent != event3);
}
之前最常用的也就是(?:),最近遇到(?)和(??)感觉还是挺有意思的。
1、可空类型修饰符(?)
int? a = null;
对比试试
int a = null;
2、空合并运算符(??)
用于定义可空类型和引用类型的默认值。如果此运算符的左操作数不为null,则此运算符将返回左操作数,否则返回右操作数。
例如:a ?? b 当a为null时则返回b,a不为null时则返回a本身。
string a = null;
string b = "b";
string c = "c";
var d = a ?? b ?? c; //"b"
3、三元(运算符)表达式(?:)
x?y:z 表示如果表达式x为true,则返回y;如果x为false,则返回z,是省略if{}else{}的简单形式。
string a = "a";
var b = a == "a" ? "a" : "b"; //"a"
4、具体使用案例:在不报异常的情况下取为null的lst中集合的个数
List<string> lst = null;
var a = lst?.Count ?? 0; //0
var b = lst == null ? 0 : lst.Count; //0
————————————————
泛型将类型参数的概念引入 .NET,这样就可设计具有以下特征的类和方法:在客户端代码声明并初始化这些类或方法之前,这些类或方法会延迟指定一个或多个类型。 例如,通过使用泛型类型参数 T,可以编写其他客户端代码能够使用的单个类,而不会产生运行时转换或装箱操作的成本或风险,如下所示:
//泛型类语法
// Declare the generic class.
public class GenericList<T>
{
//参数
public void Add(T input) { }
}
class TestGenericList
{
private class ExampleClass { }
static void Main()
{
// Declare a list of type int.
GenericList<int> list1 = new GenericList<int>();
list1.Add(1);
// Declare a list of type string.
GenericList<string> list2 = new GenericList<string>();
list2.Add("");
// Declare a list of type ExampleClass.
GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
list3.Add(new ExampleClass());
}
}
泛型类和泛型方法兼具可重用性、类型安全性和效率,这是非泛型类和非泛型方法无法实现的。 泛型通常与集合以及作用于集合的方法一起使用。 System.Collections.Generic 命名空间包含几个基于泛型的集合类。 非泛型集合(如 ArrayList)不建议使用,并且保留用于兼容性目的。 有关详细信息,请参阅 .NET 中的泛型。