ASP.NET CODE(代码片段),专注于ASP.NET,ADO.NET,C#等领域!

分页: 1/47 第一页 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 下页 最后页 [ 显示模式: 摘要 | 列表 ]
2月8
隐式代码表达式

就是一个标识符,之后可以跟任意数量的方法调用("()")、索引表达式("[]")及成员访问表达式(".")。但是,除了在"()"或者"[]"里面,是不允许空格存在的。

例如,下面是一些合法的Razor隐式表达式:
[codes=c#]
@p.Name   
@p.Name.ToString()   
@p.Name.ToString()[6 - 2]   
@p.Name.Replace("ASPX", "Razor")[i++]
[/codes]
下面是一些非法的表达式,这些表达式只有部分("==>"之后的部分)会被Razor认为是表达式。
[codes=c#]
@1 + 1 ==> @   
@p++ ==> @p   
@p    .   Name ==> @p   
@p.Name.Length – 1 ==> @p.Name.Length 
[/codes]
这是我们为什么需要另一个表达式语法:"@(...)"的原因,通过这个语法我们可以把任何想要的东西放到"()"里面,上面的例子用这个语法来表示就是:
[codes=c#]
@(1 + 1)    
@(p++)    
@(p    .   Name)    
@(p.Name.Length - 1)
[/codes]
而这种表示方法就是 显示代码表达式。
2月8
[codes=c#]
首先在Models文件夹下添加cs文件类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
//using System.Web.Mvc;
using Microsoft.SqlServer.Server;
namespace System.Web.Mvc//这里为了在页面中不需要引入命名空间
{
    public static class MyHtmlHelperExt
    {
        public static string MyLabel(this HtmlHelper helper,string str)
        {
            return string.Format("{0}",str);
        }
        public static HtmlString MyHtmlStringLabel(this HtmlHelper helper, string str) //扩展防止被编码化
            return new HtmlString(string.Format("{0}", str));
        }
    }
}
view页面使用实例:
<%:Html.MyHtmlStringLabel("你好") %>
[/codes]
2月8
本文目的
我们来看一个小例子,在一个ASP.NET MVC项目中创建一个控制器Home,只有一个Index:

[codes=c#]
public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var model = new DemoModel {Email = "test@test.com"};
            return View(model);
        }
    }

    public class DemoModel
    {
        [DataType(DataType.EmailAddress)]
        public string Email { get; set; }
    }
[/codes]
创建对应的强类型视图

[codes=c#]
@model TestMvc.Controllers.DemoModel

    DemoModel

    

        @Html.DisplayFor(model => model.Email)
    


[/codes]
运行一下,如果你的RP不是非常不好的情况下,会出现下面的结果:

点击在新窗口中浏览此图片

生成的是一个Email的链接。看一下email部分对应的html源文件:

[codes=c#]

        test@test.com

[/codes]
对于不求甚解的人来说,这很正常啊,正常的就像1+1=2一样。但对于勤学好问的同学来说,问题来了。

为什么生成的是一个email链接,不是一个纯文本?

因为我用DataType指明了它是email!

那DataType是如何指导Model生成html的?

如果你对这些问题感兴趣,请你看下去。



Model的兄弟--ModelMetadata
      在介绍Model如何能在View中正常显示之前,不得不提一下他的兄弟ModelMetadata这个类。ModelMetadata实现对Model的一些特征进行描述(如Model的类型、Model的值,Model要显示的模板 ),并且实现了对Model的所有属性值进行描述(递归结构)。有了这个兄弟,Model才能知道如何在View中正常显示【注意:这里特指的是用HtmlHelper的系列扩展方法(如Display/DiaplayFor/EditorFor等)方法在View中显示。如果你是在View中直接取Model的值用html显示,你可以暂不用关心ModelMetadata。但!!不要觉得这样你就不用了解ModelMetadata了,因为MVC中还有一个核心与它息息相关---Model绑定与验证,所以我建议你还是先认识一下这位好兄弟】,让我们来看看这个兄弟长什么样:

[codes=c#]
    public class ModelMetadata
    {
        private readonly Type _modelType;       //Model的类型
        private readonly string _propertyName;  //属性名称
        private object _model;                  //Model的值
        private Func _modelAccessor;    //为了用Lambd给Model传值(这是潮流)
        private IEnumerable _properties;  //Model属性值的ModelMetadata集合
        
        //通过子类的ComputeXX系列函数将Model的注解特性赋值到下面几个属性
        public virtual string DataTypeName { get; set; }
        public virtual string Description { get; set; }
        public virtual string DisplayFormatString { get; set; }
        public virtual string DisplayName { get; set; }
        (其它略,属性太多了,影响阅读...)

        public object Model
        {
            get
            {
                if (_modelAccessor != null)
                {
                    _model = _modelAccessor();
                    _modelAccessor = null;
                }
                return _model;
            }
        }

        public virtual IEnumerable Properties
        {
            get
            {
                if (_properties == null)
                {
                    IEnumerable originalProperties = Provider.GetMetadataForProperties(Model, RealModelType);
                    _propertiesInternal = SortProperties(originalProperties.AsArray());
                    _properties = new ReadOnlyCollection(_propertiesInternal);
                }
                return _properties;
            }
        }

        protected ModelMetadataProvider Provider { get; set; }    //ModelMetadata的创建者(后面会有介绍)
        public virtual string TemplateHint { get; set; }          //Model显示用的模板名称

    }
[/codes]
      然而在MVC中默认使用的却不是这个类,而是它的子类CachedDataAnnotationsModelMetadata(其实中间还隔着一个CachedModelMetadata类,因为该类只是做了简单的封装,为了方便读者理解,在此省略)。CachedDataAnnotationsModelMetadata做的最主要的一件事情就是通过一系列的Compute函数得到Model上注解特性的值,并把这些值赋值到对应的属性。如下:

[codes=c#]
    public class CachedDataAnnotationsModelMetadata : CachedModelMetadata
    {
        public CachedDataAnnotationsModelMetadata(CachedDataAnnotationsModelMetadataProvider provider, Type containerType, Type modelType, string propertyName, IEnumerable attributes)
            : base(provider, containerType, modelType, propertyName, new CachedDataAnnotationsMetadataAttributes(attributes.ToArray()))
        {
             PrototypeCache = new CachedDataAnnotationMetadataAttributes(attributes.ToArray());  //这个赋值应该在它的父类CachedModelMetadata中执行的,这里简化一下,方便阅读
        }

        protected override string ComputeDataTypeName()
        {
            if (PrototypeCache.DataType != null)
            {
                return PrototypeCache.DataType.ToDataTypeName();
            }return base.ComputeDataTypeName();
        }

        public override string DataTypeName{ get{ return ComputeDataTypeName();}}
    }
[/codes]
      注意代码中两个红色的部分,把Model的注解特性存在PrototypeCache里面,这样就可以通过反射得到注解特性的值了。比如文章开始处的DemoModel的属性Email对应的CachedDataAnnotationsModelMetadata对象中 DataTypeName最终被赋值为“EmailAddress”,等介绍完下一位重量级人物后,会详解具体调用过程。

ModelMetadata的创建者ModelMetadataProvider
我们还要来认识一位重量级的人物:ModelMetadata的创建者:

[codes=c#]
public abstract class ModelMetadataProvider
    {
        public abstract IEnumerable GetMetadataForProperties(object container, Type containerType);
        public abstract ModelMetadata GetMetadataForProperty(Func modelAccessor, Type containerType, string propertyName);
        public abstract ModelMetadata GetMetadataForType(Func modelAccessor, Type modelType);
    }
[/codes]
      它是一个纯抽象类。该类的第一级子类非常重要,看一下代码:

[codes=c#]
public abstract class AssociatedMetadataProvider : ModelMetadataProvider
    {
        private static void ApplyMetadataAwareAttributes(IEnumerable attributes, ModelMetadata result)
        {
            foreach (IMetadataAware awareAttribute in attributes.OfType())
            {
                awareAttribute.OnMetadataCreated(result);
            }
        }

        protected abstract ModelMetadata CreateMetadata(IEnumerable attributes, Type containerType, Func modelAccessor, Type modelType, string propertyName);

        public override ModelMetadata GetMetadataForType(Func modelAccessor, Type modelType)
        {
            //得到Model上上面的Attribute
            AttributeList attributes = new AttributeList(GetTypeDescriptor(modelType).GetAttributes());
            //创建ModelMetadata
            ModelMetadata result = CreateMetadata(attributes, null /* containerType */, modelAccessor, modelType, null /* propertyName */);
            //创建ModelMetadata后,用所有实现IMetadataAware接口的Attribute对ModelMetadata进行改造
            ApplyMetadataAwareAttributes(attributes, result);
            return result;
        }

        protected virtual ICustomTypeDescriptor GetTypeDescriptor(Type type)
        {
            return TypeDescriptorHelper.Get(type);
        }
    }
[/codes]
      注意红色的部分,正是因为有这样一个处理,用户就可以通过自已自定义扩展实现IMetadataAware接口,对ModelMetadata进行再加工处理。



      根据上面ModelMetadata讲解,我们知道,MVC中默认使用的是CachedDataAnnotationsModelMetadata这个类,于是对应ModelMetadataProvider的最终子类CachedDataAnnotationsModelMetadataProvider。

      当外部想通过GetMetadataForType来得到ModelMetadata时,内部会调用CreateMetadata,再根据原型模式调用CreateMetadataPrototype或CraeteMetadataFromPrototype实现最终创建过程:

[codes=c#]
public class CachedDataAnnotationsModelMetadataProvider : CachedAssociatedMetadataProvider
{
    protected override CachedDataAnnotationsModelMetadata CreateMetadataPrototype(IEnumerable attributes, Type containerType, Type modelType, string propertyName)
    {
        return new CachedDataAnnotationsModelMetadata(this, containerType, modelType, propertyName, attributes);
    }

    protected override CachedDataAnnotationsModelMetadata CreateMetadataFromPrototype(CachedDataAnnotationsModelMetadata prototype, Func modelAccessor)
    {
        return new CachedDataAnnotationsModelMetadata(prototype, modelAccessor);
    }
}
[/codes]
       同MVC的路由表RouteTable一样,ModelMetadataProvider也有一个静态的ModelMetadataProviders变量Current来提供默认的ModelMetadataProvider。简化代码如下:

[codes=c#]
public class ModelMetadataProviders
    {
        private static ModelMetadataProviders _instance = new ModelMetadataProviders();
        private ModelMetadataProvider _currentProvider;

        internal ModelMetadataProviders()
        {
           _currentProvider=new CachedDataAnnotationsModelMetadataProvider();
        }

        public static ModelMetadataProvider Current
        {
            get { return _instance._currentProvider; }
            set { _instance._currentProvider = value; }
        }
    }
[/codes]
终极解密
知道了这两位重量级的大员后,现在我们回到文章开始的代码:

Html.DisplayFor(model => model.Email)
当View中执行这句时,执行HtmlHelper的扩展函数,正式进入漫长的生成MvcString旅程:
点击在新窗口中浏览此图片
http://www.cnblogs.com/DotCpp/

     【注意,这个图中代码是经过N重简化而来,实际调用流程复杂无比(全是在TemplateHelpers中跳转),函数参数多如牛毛,实在不忍让大家看的痛苦】

      红色线是程序执行的主流程,后来的执行主场景都是在TemplateHelpers里面完成。

      从黄色线可以看出ModelMetadata是通过调用ModelMetadata本身的静态函数FromLambdExpression--->GetMetadataFromProvider,最终由ModelMetadataProviders完成创建。

     再来看看桔黄色部分。MVC中有一个DefaultDisplayTemplates的类,存储了诸如Boolean/String/Html/Email等等数据类型的模板,MVC最终根据ViewData中的ModelMetadata.DataType的值找到对应的模板,最终完成HTML字符串的输出,作为WebViewPage.ExecutePageHierarchy的一部分(WebViewPage请参看:仅此一文让你明白ASP.NET MVC 之View的显示(仅此一文系列二))。



结语
      本文只是用了ModelMetadata的一个DataType属性做为例子,让你了解在Model中添加注解特性是如何被ModelMetadata使用的。还有其它很多Model注解特性(如ReadOnlyAttribute/RequiredAttribute/UIHintAttribute等等)都和该原理类似。

      其实ModelMetadata在view显示中的作用是有限的,因为很多开发人员都不喜欢用这种前台显示方式,尤其随着json的大量使用,与JQUERY等前台的完美结合。但它有属于它的舞台----Model绑定与验证,敬请期待!

     希望新手看的明白,老手多提意见。如果你觉得对你有帮助,请让更多人知道它:)
10月9
IQueryable与IList差别之处

IList(IList)会立即在内存里创建持久数据,这就没有实现“延期执行(deferred execution)”,如果被加载的实体有关联实体(associations),此关联实体不会被加载(既不立即加载,也不延迟加载)。

IQeurable(IQuerable)不会立即在内存里创建持久数据,只有遍历它(如通过foreach)、把它转换成List等情况下才会向内存加载数据,它可以实现“延期执行”,如果当前被加载的实体有关联实体(associations),此关联实体可被接下来的访问加载。

看下面一段代码:
//IList的情况
IList users = res.ToList(); //此时已把users加载到内存,而每个user的关联实体(UserInfos)未
                       //被加载,所以下一行代码无法顺利通过
var ss = users.Where(p => p.UserInfos.ID != 3); //此处报错,因为P的UserInfos实体无法被加载

// IQuerable的情况
IQueryable users = res.AsQueryable(); //users未被立即加载,关联实体可通过“延迟加载”获
                                   //得
var ss = users.Where(p => p.UserInfos.ID != 3);//此处顺利获得对应的ss





IEnumerable接口
公开枚举器,该枚举器支持在指定类型的集合上进行简单迭代。也就是说:实现了此接口的object,就可以直接使用foreach遍历此object;
IQueryable 接口
它继承 IEnumerable 接口,而因为.net版本加入Linq和IQueryable后,使得IEnumerable不再那么单调,变得更加强大和丰富。
为了区别两个接口,我们通过一个实际的例子来解释一下。
根据上篇随笔的实例,编写如下代码:
复制代码
static void Main(string[] args)
        {
            //创建数据库访问网关
            using (SchoolDBEntities schoolEntities = new SchoolDBEntities())
            {
                //查询的结果放入IQueryable接口的集合中
                IQueryable classesIQue = (from c in schoolEntities.T_Class
                                                   orderby c.ID
                                                     select c).Skip(3).Take(3);
                //注意这个AsEnumerable()在分页查询之前,先将其转换成IEnumerable类型
                IEnumerable classesIEnu = (from c in schoolEntities.T_Class
                                                    orderby c.ID  
                                                    select c).AsEnumerable().Skip(3).Take(3);
                //因为启用了延迟加载机制,所以下面调用一下,才会真正去读取数据库
                int i = 0;
                foreach (var c in classesIQue)
                {
                    i++;
                }
                Console.WriteLine(i);
                foreach (var c in classesIEnu)
                {
                    i++;
                }
                Console.WriteLine(i);
            }
            Console.WriteLine("OK");
            Console.ReadKey();
        }




测试结果
IQueryable和IEnumerable都是延时执行(Deferred Execution)的,而IList是即时执行(Eager Execution)
IQueryable和IEnumerable在每次执行时都必须连接数据库读取,而IList读取一次后,以后各次都不需连接数据库。前两者很容易造成重复读取,性能低下,并且可能引发数据不一致性
IQueryable和IEnumerable的区别:IEnumberalb使用的是LINQ to Object方式,它会将AsEnumerable()时对应的所有记录都先加载到内存,然后在此基础上再执行后来的Query。所以上述TestIEnumerable例子中执行的SQL是"select top(5) ...",然后在内存中选择前两条记录返回。
以下是一个IQueryable引发数据不一致性的例子:记录总数和记录详情两者本应一致,但由于IQueryable前后两次读取数据库,结果是现实有10条记录,却输出11条详情。
IQueryable Data Inconsistancy
复制代码
    IQueryable products = ctx.Products.All();
    //开始的时候数据库product表中有10条记录, count = 10
    int count = products.Count();
    Console.WriteLine("Count of products:"+count);  
        
    //此时另一进程添加一个产品进数据库
    //会重新读取数据库并输出11个产品名称
    foreach (Product p in products)      
    {
    Console.WriteLine(p.ProductName);    
    }
复制代码
结论
基于性能和数据一致性这两点,我们使用IQueryable时必须谨慎,而在大多数情况下我们应使用IList。
当你打算马上使用查询后的结果(比如循环作逻辑处理或者填充到一个table/grid中),并且你不介意该查询会即时执行,使用ToList()
当你希望查询后的结果可以供调用者(Consummer)作后续查询(比如这是一个"GetAll"的方法),或者你希望该查询延时执行,使用AsQueryable()




IList,IQeurable,IEnumble和List 的区别
IList,IQeurable,IEnumble和List 的区别主要如下:

1.IList(IList)会立即在内存里创建持久数据,这就没有实现“延期执行(deferred execution)”,而是一次性将数据加载进来,如果被加载的实体有关联实体(associations),此关联实体不会被加载(既不立即加载,也不延迟加载)

2.IQeurable(IQuerable)不会立即在内存里创建持久数据,只有遍历它(如通过foreach)、把它转换成List等情况下才会向内存加载数据,它可以实现“延期执行”,如果当前被加载的实体有关联实体(associations),此关联实体可被接下来的访问加载。在每次执行时都必须连接数据库读取,而IList读取一次后,以后各次都不需连接数据库。IQeurable 很容易造成重复读取,性能低下,并且可能引发数据不一致性



1
2
3
4
5
6
7
8
9
//IList
IList users = res.ToList(); //此时已把users加载到内存,而每个user的关联实体(UserInfos)未
                                       //被加载,所以下一行代码无法顺利通过
var ss = users.Where(p => p.UserInfos.ID != 3); //此处报错,因为P的UserInfos实体无法被加载

// IQuerable的
IQueryable users = res.AsQueryable(); //users未被立即加载,关联实体可通过“延迟加载”获
                                   //得
var ss = users.Where(p => p.UserInfos.ID != 3);//此处顺利获得对应的ss


3.IEnumberalb使用的是LINQ to Object方式,它会将AsEnumerable()时对应的所有记录都先加载到内存,然后在此基础上再执行后来的Query。

4.List <>是泛型类,它已经实现了IList <>定义的那些方法,IList list=new List();
只是想创建一个基于接口IList的对象的实例,这个接口是由List实现的。只是希望使用到IList接口规定的功能而已



总结:

基于性能和数据一致性这两点,使用IQueryable时必须谨慎,而在大多数情况下我们应使用IList。

当你打算马上使用查询后的结果(比如循环作逻辑处理或者填充到一个table/grid中),并且你不介意该查询即时被执行后的结果可以供调用者(Consummer)作后续查询(比如这是一个"GetAll"的方法),或者你希望该查执行,使用ToList()
当你希望查询后的结果可以供调用者(Consummer)作后续查询(比如这是一个"GetAll"的方法),或者你希望该查询延时执行,使用AsQueryable()
按照功能由低到高:List IList  IQueryable IEnumerable
按照性能由低到高:IEnumerable IQueryable IList  List
参考文档:  http://www.cnblogs.com/xpvincent/p/3605068.html

http://www.cnblogs.com/hiteddy/archive/2011/10/01/Difference_among_IQueryable_IEnumeralb_IList_in_Entity_Framework.html
10月8
[codes=c#]
MVC中HtmlHelper用法大全参考

解析MVC中HtmlHelper控件7个大类中各个控件的主要使用方法(1)
2012-02-27 16:25
HtmlHelper类在命令System.Web.Mvc.Html之中,主要由7个静态类组成,它们分别是FormExtensions类,InputExtensions类,LinkExtensions类,SelectExtensions类,TextExtensions类,ValidationExtensions类,RenderPartialExtensions类。
为了方便开发者使用HtmlHelper控件,在视图ViewPage类中设置了一个属性Html它就是HtmlHelper类型。
1.FormExtensions类
定义了3中类型的扩展方法BeginForm,BeginRouteForm,EndForm。
(1) BeginForm (实现表单定义的开始部分)
重载方法有13个:
BeginForm();
BeginForm(Object routeValues);
BeginForm(RouteValueDictionary routeValues);
BeginForm(string actionName,string controllerName);
BeginForm(string actionName,string controllerName,object routeValues);
BeginForm(string actionName,string controllerName,RouteValueDictionary routeValues);
BeginForm(string actionName,string controllerName,FormMethod method);
BeginForm(string actionName,string controllerName,object routeValues,FormMethod method);
BeginForm(string actionName,string controllerName,RouteValueDictionary routeVaues,FormMethod method);
BeginForm(string actionName,string controllerName,FormMethod method,object htmlAttributes);
BeginForm(string actionName,string controllerName,FormMethod method,IDictionary htmlAttributes);
BeginForm(string actionName,string controllerName,object routeValues,FormMethod method,object htmlAttributes);
BeginForm(string actionName,string controllerName,RouteValueDictionary routeValues,FormMethod method,IDictionary htmlAttributes);
对于第二个重载方法可以设置如下:
Html.BeginForm(new{action="action",controller="actroller",id="2"});
在上述代码中,设置了路由值的一个实例化对象,输出的HTML语句是:

对于最后一个第十三个方法的最后一个参数是实例化对象设置相关属性的值例如class,width等。
(2)BeginRouteForm (主要实现表单定义的开始部分,以路由的方法设置action的值)
有12个重载方法:
BeginRouteForm(object routeValues);
BeginRouteForm(RouteValueDictionary routeValues);
BeginRouteForm(string routeName);
BeginRouteForm(string routeName,object routeValues);
BeginRouteForm(string routeName,RouteValueDictionary routeValues);
BeginRouteForm(string routeName,FormMethod method);
BeginRouteForm(string routeName,object routeValues,FormMethod method);
……
对于第一个重载方法:
Html.BeginRouteForm(new {action="action"});
Home是页面所在的目录
BeginForm与BeginRouteForm的区别就在于第一个的action是action第二个的action是Home/action
(3)EndForm(实现表单的定义的结束部分)
Html.EndForm();
相当于


InputExtensions类有5种类型的扩展方法,可在视图中设置checkBox,hidden,password,radioButton,textBox控件。
(1)CheckBox 实现复选框控件有6个重载方法
CheckBox(string name);
CheckBox(string name,bool isChecked);
CheckBox(string name,bool isChecked,object htmlAttributes);
CheckBox(string name,object htmlAttributes);
CheckBox(string name,Idictionary htmlAttributes);
CheckBox(string name,bool isChecked,Idictionary htmlAttributes);
设置复选框的实现代码:
<%=Html.BeginForm("CheckBox","Home") %>

设置字体:
<%=Html.CheckBox("MyCheckBox1",true,new{id="checkBox1"})%>

<%=Html.CheckBox("MyCheckBox2",false,new{id="checkBox2"})%>






<%Html.EndForm();%>
运行上述代码,上述复选框的设置代码对应的HTML语句:




在后台检索checkBox
public ActionResult CheckBox (FormCollection formCollection)
{
bool MyCheckBox1=formCollection[0].Contains("true");//检索第一个复选框是否被选中
bool MyCheckBox2=formCollection["MyCheckBox2"].Contains("true");//检索名字是MyCheckBox2的复选框是否倍选中
ViewData["CheckBox1"]=MyCheckBox1;
ViewData["CheckBox2"]=MyCheckBox2;
return View();
}
(2)Hidden 表单中的隐藏数值,有4个重载方法。
Hidden(string name);
Hidden(string name,object value);
Hidden(string name,object value,object htmlAttributes);
Hidden(string name,object value,Idictionary htmlAttributes);
eg:
Html.Hidden("testName");对应输出的Html语句如下:

(3)Password 主要是输入密码的文本框,有4个重载方法。
Hidden(string name);
Password (string name,object value);
Password (string name,object value,object htmlAttributes);
Password (string name,object value,Idictionary htmlAttributes);
eg:
Html.Password ("MyPwd");对应输出的Html语句如下:

--------------------------------------------------------------------------------------------


HTML扩展类的所有方法都有2个参数:
以textbox为例子
public static string TextBox( this HtmlHelper htmlHelper, string name, Object value, IDictionary htmlAttributes )
public static string TextBox( this HtmlHelper htmlHelper, string name, Object value, Object htmlAttributes )
这2个参数代表这个html标签的属性集合。使用方法如下。

1.ActionLink
<%=Html.ActionLink("这是一个连接", "Index", "Home")%>
带有QueryString的写法
<%=Html.ActionLink("这是一个连接", "Index", "Home", new { page=1 },null)%>
<%=Html.ActionLink("这是一个连接", "Index", new { page=1 })%>
有其它Html属性的写法
<%=Html.ActionLink("这是一个连接", "Index", "Home", new { id="link1" })%>
<%=Html.ActionLink("这是一个连接", "Index",null, new { id="link1" })%>
QueryString与Html属性同时存在
<%=Html.ActionLink("这是一个连接", "Index", "Home", new { page = 1 }, new { id = "link1" })%>
<%=Html.ActionLink("这是一个连接", "Index" , new { page = 1 }, new { id = "link1" })%>

生成结果为:
这是一个连接
带有QueryString的写法
这是一个连接
这是一个连接
有其它Html属性的写法
这是一个连接
这是一个连接
QueryString与Html属性同时存在
这是一个连接
这是一个连接

2.RouteLink
跟ActionLink在功能上一样。
<%=Html.RouteLink("关于", "about", new { })%>
带QueryString
<%=Html.RouteLink("关于", "about", new { page = 1 })%>
<%=Html.RouteLink("关于", "about", new { page = 1 }, new { id = "link1" })%>

生成结果:
关于
关于
关于
3.Form 2种方法
<%using(Html.BeginForm("index","home",FormMethod.Post)){%>
<%} %>

<%Html.BeginForm("index", "home", FormMethod.Post);//注意这里没有=输出%>
<%Html.EndForm(); %>

生成结果:

4.TextBox , Hidden ,
<%=Html.TextBox("input1") %>
<%=Html.TextBox("input2",Model.CategoryName,new{ @style = "width:300px;" }) %>
<%=Html.TextBox("input3", ViewData["Name"],new{ @style = "width:300px;" }) %>
<%=Html.TextBoxFor(a => a.CategoryName, new { @style = "width:300px;" })%>

生成结果:






5.TextArea
<%=Html.TextArea("input5", Model.CategoryName, 3, 9,null)%>
<%=Html.TextAreaFor(a => a.CategoryName, 3, 3, null)%>

生成结果:
10月8
MVC三个组成部分:Model 、View、Controller。今天主要想和大家分享的是View这一块。微软的MVC摒弃了之前的aspx页面的拖拖控件就能搞定的理念,因为发现那样会把程序员惯成傻子,而做出来的网站毫无性能可言,慢的像猪头!所以在展示页面View这一部分的操作几乎就是纯手工写html代码了。这对于程序员来说也挺苦恼的,因为从轻松拖控件直接升级为纯手工写代码(当然,可能难度不大,但是其中的麻烦是不可言喻的)。幸好微软推出了HtmlHelper,方便了我们写html代码,大大提高了效率。

  何为HtmlHelper?HtmlHelper也好SQLHelper也好,说白了就是把很多代码封装起来,然后供我们调用,用于节省开发时间,降低错误率。好了闲言少叙,开始正题;如果我们用MVC做一个简单的文章回复功能,View层中写一个TextBox一个TextArea一个Submit按钮,TextBox写标题TextArea写内容然后一点Submit就可以搞定了,这样看起来没什么问题。但是想一想如果在提交回复时出现了错误,没提交成功。按道理说在TextBox和TextArea中应该还保存刚才我们写的内容的,但是可惜View层中已经没有了ViewState。于是乎悲催的事情发生了,我们写了半天的评论,一点按钮,一个小错误没成功,回来后啥都没了,傻眼了!这样该怎么办呢?好办啊!在Controller里面给控件赋值不就可以了吗?想法很好,但可惜MVC模式中Controller操作View中的控件是犯法的!这怎么办?于是乎htmlhelper应运而生! 在View中将手写的TextBox和TextArea删掉,然后用HtmlHelper,具体代码如下:标题: <%:Html.TextBox("txtTitle","txtTitle") %>评论内容: <%:Html.TextArea("txtContent") %>这两个尖括号里里面的东西就是HtmlHelper了。以第一个为例:先写尖括号百分号然后是冒号,但是我们知道啊在WebForm时代,我们也这样在html里面加C#代码但是百分号后面往往是等号,那冒号和百分号的区别是什么呢?诸位可以试一下,冒号包裹的内容如果含有尖括号等的html标签,会识别出来。而等号不识别而是直接把内容显示出来。Html.TextBox里面的参数,第一个是该TextBox的Name属性,第二个是Value属性,当然还可以设置它的样式了 <%:Html.TextBox("txtTitle", "txtTitle", new { disable="none",....})%>大括号里面写属性,多个时用逗号隔开。在Controller里面可以通过ViewData["txtTitle"]进行取值和赋值。这样子一个HtmlHelper基本上就出炉了。

  当然有很多公司都有自己的HtmlHelper,然后今天就研究了一下,应该怎样写出自己的HtmlHelper,然后查看代码发现了所谓的每一个控件的HtmlHelper其实就是分别写一个类然后对HtmlHelper进行扩展,然后便写了一个扩展的类实现了一个特殊的Span标签的展示。具体方法如下:新建一个类,命名为SpanExtensions这个类是一个静态类,Public Static Class SpanExtensions  里面写一个方法,GetSpan方法,当然这也是一个静态方法,同时实现对HtmlHelper的扩展,还需要传入一个里面显示内容的参数具体代码如下:

public static string GetLabel(this HtmlHelper helper, string txt)  

  {            

            return string.Format("{0}", txt);

}

  这样在前面的View里面用Htmlhelper调用的时候发现没有,怪了,明明写了的,后来发现原来是SpanExtensions类的命名空间和View不一样,我想引用然后发现如果以后用这个方法的地方很多就太麻烦了,然后就直接把SpanExtensions的命名空间改为View的命名空间,然后就找到了,写完后一运行!发现:亲娘来,连html标签都出来了,难不成还得转?后来看了看HtmlHelper里面的TextBox发现返回值不一样,它的返回值是一个MvcHtmlString类型,啥东西啊?没见过!于是我就想把MvcHtmlString这个东西和String能够联系起来,后来整出来了,代码如下:  MvcHtmlString mc = MvcHtmlString.Create(string.Format("{0}", txt)); 这样直接返回mc就可以搞定了!
10月8
[codes=c#]
string controllerName =
(string)htmlHelper.ViewContext.RouteData.GetRequiredString("controller");

string areaName =
(string)htmlHelper.ViewContext.RouteData.DataTokens["area"];
[/codes]

在 controller 中可以使用 ControllerContext 取得:

[codes=c#]
ControllerContext.RouteData.Values["controller"]
ControllerContext.RouteData.Values["action"]
[/codes]

在 view 中可以使用 ViewContext:
[codes=c#]
ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["action"]
[/codes]
7月19

clickone

08:56ASP.NET  From: 本站原创
ClickOnce 是一种部署技术,使用该技术可创建自行更新的基于 Windows 的应用程序,这些应用程序可以通过最低程度的用户交互来安装和运行

ClickOnce 部署克服的主要问题

ClickOnce 部署克服了部署中所固有的三个主要问题:
更新应用程序的困难

使用 Microsoft Windows Installer 部署,每次应用程序更新,用户都必须重新安装整个应用程序;使用 ClickOnce 部署,则可以自动提供更新。只有更改过的应用程序部分才会被下载,然后从新的并行文件夹重新安装完整的、更新后的应用程序。
对用户的计算机的影响

使用 Windows Installer 部署时,应用程序通常依赖于共享组件,这便有可能发生版本冲突;而使用 ClickOnce 部署时,每个应用程序都是独立的,不会干扰其他应用程序。
安全权限

Windows Installer 部署要求管理员权限并且只允许受限制的用户安装;而 ClickOnce 部署允许非管理用户安装应用程序并仅授予应用程序所需要的那些代码访问安全权限。
过去,这些问题有时会使开发人员决定创建 Web 应用程序而不是基于 Windows 的应用程序,为便于安装而牺牲了 Windows窗体丰富的用户界面和响应性。对于使用 ClickOnce 部署的应用程序,您可以集这两种技术的优势于一身。

ClickOnce安全的工作方式

核心 ClickOnce 安全基于证书、代码访问安全性策略和 ClickOnce 信任提示。
证书

Authenticode 证书用于验证应用程序发布者的真实性。
通过将 Authenticode 用于应用程序部署,ClickOnce 可帮助防止有害程序将自己伪装成来自已确定的可信任源的合法程序。 (可选)证书也可以用于为应用程序和部署清单签名,以证明文件未被篡改。 有关更多信息,请参见ClickOnce 和 Authenticode。 证书还可以用于为客户端计算机配置一个受信任的发布者的列表。 如果某个应用程序来自受信任的发布者,则可以在无需任何用户交互的情况下安装该应用程序。 有关更多信息,请参见受信任的应用程序部署概述。
代码访问安全性

代码访问安全性可帮助限制代码对受保护资源的访问。
大多数情况下,您可以选择 Internet 区域和本地 Intranet 区域来限制权限。 使用“项目设计器”中的“安全性”页可以请求适合于应用程序的区域。 您也可以使用受限权限调试应用程序来模拟最终用户的体验。 有关更多信息,请参见ClickOnce 应用程序的代码访问安全性。
ClickOnce 信任提示

如果应用程序请求的权限超出区域的允许范围,则会提示最终用户做出信任决定。
最终用户可以决定是否信任 ClickOnce 应用程序(如 Windows Forms 应用程序、Windows Presentation Foundation 应用程序、控制台应用程序、XAML 浏览器应用程序和 Office 解决方案)以允许其运行。 有关更多信息,请参见如何:配置 ClickOnce 信任提示行为。
6月16
.net学习路线

入门篇1.         学习面向对象(OOP)的编程思想

许多高级语言都是面向对象的编程,.NET也不例外。如果您第一次接触面向对象的编程,就必须理解类、对象、字段、属性、方法和事件、封装、继承和多态性、重载、重写等概念。需要说明的是,微软的产品帮助文档做得非常完善,而且查询相当方便,入门者不得不看。安装完Visual Studio.NET2003(或者Visual Studio.NET2002)后,在“程序”组里有一个Visual Studio 组合帮助集合。初学者从帮助文档就会获得许多知识。

2.         选择一门语言,学习语法及相关基础知识

选 择语言的标准:根据你自己的需求和个人的技术背景。在.NET平台下,C#、VB.NET都是调用Framework的类库,效率基本一样,C#的语法严谨,适合以前C++、VC的程序员。VB.NET不区分大小写,写法随意一些.,自动缩进,适合以前VB的程序员,微软也一再提倡用VB.NET进行快速开发。VC++.NET更接近底层,可以用托管和非托管两种方式进行编程。

选择了需要使用的语言后,我们需要了解语言的语法规则,包括语句、类型、表达式、运算符、函数等等,我建议一开始写程序就要养成良好的编程风格,规范地进行变量的命名,在代码中写好注释。这对以后的软件开发生涯都是很有意义的。

3.         理解.NET思想并熟悉框架类库(Framework Class Library)

我们借用一幅图来说明一下公共语言运行库(CLR)、框架类库(FCL)与应用程序之间以及与整个系统之间的关系。

首 先,我们要了解公共语言运行库、程序集、通用类型系统的概念。在此基础上,学习.NET框架类库。.NET框架类库是一个与公共语言运行库紧密集成的可重用的类型集合。.NET 框架类库封装了大部分Win32 API,许多以前需要调用API才能实现的功能,在.NET下非常容易就实现,许多情况下只需要一句话就足够了。所以,我们在程序设计的时候要尽量避免调用 Win32API。学习.NET 框架类库的捷径:掌握常用的类库,其它不常用的类库只需要了解,用到的时候查阅即可。
6月16

knockoutjs介绍

17:22ASP.NET » knockoutjs  From: 本站原创
knockoutjs,简称ko,是一个轻量级的MVVM框架,通过简易的UI绑定语法,实现动态更新UI。
主页:http://knockoutjs.com/index.html
源码:http://github.com/SteveSanderson/knockout

ko的特点:
声明式绑定:通过简洁易读的data-bind语法,将DOM元素与ViewModel关联起来。
UI自动更新:当模型(ViewModel)状态更新时,自动更新UI界面。
依赖跟踪:在模型数据间建立隐式的关系链。
模板化:快速生成复杂,可嵌套UI模型数据的函数。

更多特性:
免费开源,基于MIT许可证。
纯javascript实现,可以与任何web框架共用。
小巧,压缩精简后只有42kb,开启g-zip后只剩15kb。
无其他依赖。
支持所有主流浏览器,IE 6+,Firefox 2+,Chrome,Opera,Safari (desktop/mobile)。
完善的文档,包括API文档,在线实例,交互教程。(在官网导航也可找到)

下载
访问该页面来获取最新的knockoutjs:http://knockoutjs.com/downloads/index.html
包括用于生产环境的版本和调试版本,调试版本仅在当你打算了解ko框架工作原理时使用,请不要在生产环境中使用,因为它对外暴露了额外的不被支持的API。

安装
使用ko很简单,只需要在html文件里通过script标签引入ko的js文件,比如

分页: 1/47 第一页 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 下页 最后页 [ 显示模式: 摘要 | 列表 ]