<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>幻想曲.Net &#187; Asp.Net</title>
	<atom:link href="http://yibin.us/tag/dotnet/feed" rel="self" type="application/rss+xml" />
	<link>http://yibin.us</link>
	<description>面朝大海，春暖花开</description>
	<lastBuildDate>Fri, 17 Jun 2011 01:57:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>给BlogEngine增加日志点击数</title>
		<link>http://yibin.us/archives/6060</link>
		<comments>http://yibin.us/archives/6060#comments</comments>
		<pubDate>Tue, 23 Dec 2008 12:57:45 +0000</pubDate>
		<dc:creator>幻想曲</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[Asp.Net]]></category>

		<guid isPermaLink="false">http://yibin.us/?p=6060</guid>
		<description><![CDATA[有朋友在留言时提到，所以这里放出来。我用的是sqlserver，如果是xml就得改相应的代码了。先在数据表中增加一字段：hit，给post.cs中增加一Hit字段。同时更改provider的代码，这里就不给出来了。 blogservice.cs添加UpdateHit(guid id)方法 public static void UpdateHit(guid id) { LoadProviders(); _provider.UpdateHit(id); } sqldataprovider.cs public override void UpdateHit(guid id) { string sqlQuery = " update dbo.be_Posts set hit = hit+1 where postid=@id"; SqlHelper.ExecuteNonQuery(SqlHelper.ConnectionString, CommandType.Text, sqlQuery, new SqlParameter("@id", id)); } post.cs public static void UpdateHit(guid id) { Posts.Find(delegate(Post p) { return p.Id== id; }).Hit++; //更新内存数据 BlogService.UpdateHit(id); //更新数据库记录 [...]]]></description>
			<content:encoded><![CDATA[<p>有朋友在留言时提到，所以这里放出来。<br />我用的是sqlserver，如果是xml就得改相应的代码了。<br />先在数据表中增加一字段：hit，给post.cs中增加一Hit字段。<br />同时更改provider的代码，这里就不给出来了。</p>
<p><code><br />
blogservice.cs添加UpdateHit(guid id)方法<br />
 public static void UpdateHit(guid id)<br />
        {<br />
            LoadProviders();<br />
            _provider.UpdateHit(id);<br />
        }</p>
<p>sqldataprovider.cs<br />
public override void UpdateHit(guid id)<br />
        {<br />
            string sqlQuery = " update dbo.be_Posts set hit = hit+1 where postid=@id";<br />
            SqlHelper.ExecuteNonQuery(SqlHelper.ConnectionString, CommandType.Text, sqlQuery, new SqlParameter("@id", id));<br />
        }</p>
<p>post.cs<br />
 public static void UpdateHit(guid id)<br />
        {<br />
            Posts.Find(delegate(Post p) { return p.Id== id; }).Hit++;   //更新内存数据<br />
            BlogService.UpdateHit(id);  //更新数据库记录<br />
        }
</pre>
<p>post.aspx.cs<br /><code><br />
if (Request.QueryString["id"] != null &#038;&#038; Request.QueryString["id"].Length == 36)<br />
		{<br />
			Guid id = new Guid(Request.QueryString["id"]);<br />
			this.Post = Post.GetPost(id);</p>
<p>			if (Post != null)<br />
			{<br />
                      Post.UpdateHit(this.Post.Id);   //增加<br />
           ......................
</pre>
<p>更改完毕。</p>
]]></content:encoded>
			<wfw:commentRss>http://yibin.us/archives/6060/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>[BlogEngine扩展]IP2Area</title>
		<link>http://yibin.us/archives/6049</link>
		<comments>http://yibin.us/archives/6049#comments</comments>
		<pubDate>Fri, 05 Dec 2008 13:33:23 +0000</pubDate>
		<dc:creator>幻想曲</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[Asp.Net]]></category>
		<category><![CDATA[blogengine]]></category>

		<guid isPermaLink="false">http://yibin.us/?p=6049</guid>
		<description><![CDATA[该插件将评论者的IP转为地区，数据取自于http://www.ip138.com在这里表示感谢！该扩展要在CommentAdded事件上进行处理，首先添加一个字段UserArea用来保存地区。放心，这里的是异步处理的，不会造成页面的明显延迟。 代码如下： /// &#60;summary&#62; ///Ip2Area 的摘要说明 /// &#60;/summary&#62; /// [Extension("IP转为地区", "1.0", "JasonYi")] public class Ip2Area { public Ip2Area() { Post.CommentAdded += new EventHandler&#60;EventArgs&#62;(Post_CommentAdded); } void Post_CommentAdded(object sender, EventArgs e) { Comment p = sender as Comment; if(p!=null) new HttpAsyncGetIPArea(p,"http://www.ip138.com/ips.asp").Execute(); } } public class HttpAsyncGetIPArea { private Comment _comment; private string _url; public HttpAsyncGetIPArea(Comment c,string url) [...]]]></description>
			<content:encoded><![CDATA[<p>该插件将评论者的IP转为地区，数据取自于<a href="http://www.ip138.com" target="_blank">http://www.ip138.com</a><br />在这里表示感谢！<br />该扩展要在CommentAdded事件上进行处理，首先添加一个字段UserArea用来保存地区。<br />放心，这里的是异步处理的，不会造成页面的明显延迟。</p>
<p>代码如下：<br /><code><br />
/// &lt;summary&gt;<br />
///Ip2Area 的摘要说明<br />
/// &lt;/summary&gt;<br />
///<br />
[Extension("IP转为地区", "1.0", "JasonYi")]<br />
public class Ip2Area<br />
{<br />
    public Ip2Area()<br />
    {<br />
        Post.CommentAdded += new EventHandler&lt;EventArgs&gt;(Post_CommentAdded);<br />
    }</p>
<p>    void Post_CommentAdded(object sender, EventArgs e)<br />
    {<br />
        Comment p = sender as Comment;<br />
        if(p!=null)<br />
        new HttpAsyncGetIPArea(p,"http://www.ip138.com/ips.asp").Execute();<br />
    }<br />
}<br />
public class HttpAsyncGetIPArea<br />
{<br />
    private Comment _comment;<br />
    private string _url;<br />
    public HttpAsyncGetIPArea(Comment c,string url)<br />
    {<br />
        _comment = c;<br />
        _url = url;<br />
    }<br />
    public Comment comment<br />
    {<br />
        get { return _comment; }<br />
    }<br />
    private HttpWebRequest Request;</p>
<p>    public void Execute()<br />
    {<br />
        Request = (HttpWebRequest)WebRequest.Create(_url);<br />
        Request.Method = "POST";<br />
        Request.ContentType = "application/x-www-form-urlencoded";<br />
        Byte[] data = System.Text.Encoding.ASCII.GetBytes("action=2&#038;ip=" + _comment.IP);<br />
        Request.ContentLength = data.Length;<br />
        using (Stream stream = Request.GetRequestStream())<br />
        {<br />
            stream.Write(data, 0, data.Length);<br />
        }<br />
        Request.BeginGetResponse(ProcessRespose, this);<br />
    }<br />
    private void ProcessRespose(IAsyncResult async)<br />
    {<br />
        HttpAsyncGetIPArea item = (HttpAsyncGetIPArea)async.AsyncState;<br />
        try<br />
        {<br />
            using (HttpWebResponse response = (HttpWebResponse)item.Request.EndGetResponse(async))<br />
            {<br />
                string RStr = string.Empty;</p>
<p>                using (StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.Default))<br />
                {</p>
<p>                    RStr = sr.ReadToEnd();<br />
                }<br />
                Regex reg = new Regex(@"本站主数据：([^&lt;li&gt;]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase);<br />
                MatchCollection mc = reg.Matches(RStr);<br />
                string area = string.Empty;<br />
                if (mc.Count &gt; 0)<br />
                {<br />
                    area = mc[0].Value.Replace("本站主数据：", string.Empty);<br />
                }<br />
                if (!string.IsNullOrEmpty(area))<br />
                {<br />
                    string sql = "UPDATE  be_PostComment SET UserArea=@Area WHERE PostCommentID=@Id";<br />
                    SqlParameter[] para = { new SqlParameter("@Area", area), new SqlParameter("@Id", comment.Id) };<br />
                    SqlHelper.ExecuteNonQuery(SqlHelper.ConnectionString, System.Data.CommandType.Text, sql, para);<br />
                    comment.UserArea = area;<br />
                }<br />
            }<br />
        }<br />
        catch (Exception ex)<br />
        {<br />
            //throw new System.Net.WebException("Get HttpResponse Error");<br />
        }<br />
        finally<br />
        {<br />
            Request.Abort();<br />
        }<br />
    }<br />
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://yibin.us/archives/6049/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>微软推出For .Net 3.5 Chart控件</title>
		<link>http://yibin.us/archives/6038</link>
		<comments>http://yibin.us/archives/6038#comments</comments>
		<pubDate>Mon, 27 Oct 2008 14:09:21 +0000</pubDate>
		<dc:creator>幻想曲</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[Asp.Net]]></category>
		<category><![CDATA[chart]]></category>

		<guid isPermaLink="false">http://yibin.us/?p=6038</guid>
		<description><![CDATA[的确是个好消息！弥补了.Net在生成图表方面的不足，该控件支持winform与webform，不过按官方所言，该控件目前只有.Net formwork 3.5版。 控件下载：下载地址中文语言包下载：下载地址 Demo下载http://code.msdn.microsoft.com/mschart/Release/ProjectReleases.aspx?ReleaseId=1591赶快试用一下吧]]></description>
			<content:encoded><![CDATA[<p>的确是个好消息！弥补了.Net在生成图表方面的不足，<br />该控件支持winform与webform，不过按官方所言，该控件目前只有.Net formwork 3.5版。</p>
<p>控件下载：<br /><a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=130F7986-BF49-4FE5-9CA8-910AE6EA442C&#038;displaylang=en" target="_blank">下载地址</a><br />中文语言包下载：<br /><a href="http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&#038;FamilyID=581ff4e3-749f-4454-a5e3-de4c463143bd" target="_blank">下载地址</a></p>
<p>Demo下载<br /><a href="http://code.msdn.microsoft.com/mschart/Release/ProjectReleases.aspx?ReleaseId=1591" target="_blank">http://code.msdn.microsoft.com/mschart/Release/ProjectReleases.aspx?ReleaseId=1591</a><br /><a href="http://yibin.us/wp-content/uploads/20081027/2008-10-27_220535.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20081027/2008-10-27_220535.png" class="img"  /></a><br /><a href="http://yibin.us/wp-content/uploads/20081027/2008-10-27_220610.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20081027/2008-10-27_220610.png" class="img"  /></a><br /><a href="http://yibin.us/wp-content/uploads/20081027/2008-10-27_220655.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20081027/2008-10-27_220655.png" class="img"  /></a><br /><a href="http://yibin.us/wp-content/uploads/20081027/2008-10-27_220743.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20081027/2008-10-27_220743.png" class="img"  /></a><br /><a href="http://yibin.us/wp-content/uploads/20081027/2008-10-27_220806.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20081027/2008-10-27_220806.png" class="img"  /></a><br /><a href="http://yibin.us/wp-content/uploads/20081027/2008-10-27_220831.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20081027/2008-10-27_220831.png" class="img"  /></a><br /><a href="http://yibin.us/wp-content/uploads/20081027/2008-10-27_220858.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20081027/2008-10-27_220858.png" class="img"  /></a><br /><a href="http://yibin.us/wp-content/uploads/20081027/2008-10-27_220922.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20081027/2008-10-27_220922.png" class="img"  /></a><br /><a href="http://yibin.us/wp-content/uploads/20081027/2008-10-27_221006.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20081027/2008-10-27_221006.png" class="img"  /></a><br />赶快试用一下吧</p>
]]></content:encoded>
			<wfw:commentRss>http://yibin.us/archives/6038/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>[BlogEngine插件]对日志进行加密</title>
		<link>http://yibin.us/archives/6036</link>
		<comments>http://yibin.us/archives/6036#comments</comments>
		<pubDate>Sat, 25 Oct 2008 07:32:54 +0000</pubDate>
		<dc:creator>幻想曲</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[Asp.Net]]></category>
		<category><![CDATA[blogengine]]></category>

		<guid isPermaLink="false">http://yibin.us/?p=6036</guid>
		<description><![CDATA[这里的对日志加密是指输入正确密码以后才能正常访问。 示例： http://yibin.us/Archives/6035.aspx 密码：123456 针对于BlogEngine来说，可以用它丰富的插件机制来实现。 首先明确，完成这个插件需要做哪些工作： １、数据表结构的变化。要增加密码项，“密码”字段当然是少不了了。 ２、表结构的变化势必会引起Post实体类属性的变化。 ３、Post.Serving时触发事件，该事件负责针对性的改变e.Body 4、认证的实现。 这里我用的是SqlServer数据库，打开be_Posts表，执行以下语句 对应地在BlogEngine.Core.Post中增加属性AccessPassword 这里的AccessPassword不为空表明该日志需要密码才能访问。当然，这里还得修改相应的数据访问层代码，来初始化AccessPassword字段。这里略去。 下一步编写插件，针对Post.Serving事件编写，全部代码： 接下来就是实现认证这一步，我采用的是实现ICallbackEventHandler接口来进行无刷新操作。 先看很简单的js代码 .cs文件中的关于ICallbackEventHandler接口的实现 OK，整个过程就是如此，很是简单吧。 同样的原理，可以实现类似于论坛的“回复后可见”同样的功能，如果想长时间维持日志的正常查看权，可将Session换成Cookie。 另外，BlogEngine默认在web.config中将enableSessionState设为了false，请一定要设为true,否则无法使用Session! 我就是没有认真看web.config，在Session的获取上大费周折。]]></description>
			<content:encoded><![CDATA[<p>这里的对日志加密是指输入正确密码以后才能正常访问。<br />
示例：<br />
<a href="http://yibin.us/Archives/6035.aspx" target="_blank">http://yibin.us/Archives/6035.aspx</a><br />
密码：123456<br />
针对于BlogEngine来说，可以用它丰富的插件机制来实现。</p>
<p>首先明确，完成这个插件需要做哪些工作：<br />
１、数据表结构的变化。要增加密码项，“密码”字段当然是少不了了。<br />
２、表结构的变化势必会引起Post实体类属性的变化。<br />
３、Post.Serving时触发事件，该事件负责针对性的改变e.Body<br />
4、认证的实现。<br />
这里我用的是SqlServer数据库，打开be_Posts表，执行以下语句</p>
<pre class="brush: sql; title: ; notranslate">
ALTER TABLE dbo.be_Posts
ADD AccessPassword VARCHAR(100) NOT NULL DEFAULT ''
GO
</pre>
<p>对应地在BlogEngine.Core.Post中增加属性AccessPassword</p>
<pre class="brush: csharp; title: ; notranslate">
private string _AccessPassword = string.Empty;
public string AccessPassword
{
get { return _AccessPassword; }
set {
if (_AccessPassword != value) MarkChanged(&amp;quot;AccessPassword&amp;quot;);
_AccessPassword = value;
}
}
</pre>
<p>这里的AccessPassword不为空表明该日志需要密码才能访问。当然，这里还得修改相应的数据访问层代码，来初始化AccessPassword字段。这里略去。<br />
下一步编写插件，针对Post.Serving事件编写，全部代码：</p>
<pre class="brush: csharp; title: ; notranslate">
[Extension(&amp;quot;加密日志&amp;quot;,&amp;quot;1.0&amp;quot;,&amp;quot;yibin&amp;quot;)]
public class ZPostAccessExtension : System.Web.SessionState.IRequiresSessionState
{
string cookiekey = string.Empty;
public ZPostAccessExtension()
{
Post.Serving += new EventHandler&amp;lt;ServingEventArgs&amp;gt;(Post_Serving);
}

void Post_Serving(object sender, ServingEventArgs e)
{
Post p = sender as Post;
if (HttpContext.Current.User.IsInRole(&amp;quot;administrators&amp;quot;) || HttpContext.Current.User.Identity.Name == p.Author)
return;
cookiekey = &amp;quot;POSTACCESS_&amp;quot; + p.Id;
//这里很关键，用Session来判断当前用户没有权限访问，如果指定的session存在，则直接退出，否则更改e.Body值。
if (HttpContext.Current.Session[cookiekey] != null)
{
return;
}
if (!string.IsNullOrEmpty(p.AccessPassword))
{
if (e.Location == ServingLocation.PostList)
{
e.Body = &amp;quot;加密日志,您无权查看&amp;quot;;
}
else
{
e.Body = string.Format(@&amp;quot;&amp;lt;p class=&amp;quot;&amp;quot;AccessPassword&amp;quot;&amp;quot;&amp;gt;加密日志，请输入密码查阅&amp;lt;/p&amp;gt;&amp;lt;input type=&amp;quot;&amp;quot;password&amp;quot;&amp;quot; name=&amp;quot;&amp;quot;AccessPassword_{0}&amp;quot;&amp;quot; id=&amp;quot;&amp;quot;AccessPassword_{0}&amp;quot;&amp;quot; class=&amp;quot;&amp;quot;AccessPassword&amp;quot;&amp;quot; /&amp;gt;&amp;lt;input type=&amp;quot;&amp;quot;button&amp;quot;&amp;quot; value=&amp;quot;&amp;quot;确定&amp;quot;&amp;quot; title=&amp;quot;&amp;quot;确定&amp;quot;&amp;quot; onclick=&amp;quot;&amp;quot;Check();&amp;quot;&amp;quot;/&amp;gt;&amp;quot;, p.PostIdentity);
e.Body = e.Body.Replace(&amp;quot;&amp;lt;&amp;quot;, &amp;quot;&amp;lt;&amp;quot;).Replace(&amp;quot;&amp;gt;&amp;quot;, &amp;quot;&amp;gt;&amp;quot;);  //这里要对已经HtmlEncode后的字符进行还原，否则显示不正确。
}
}
}
}
</pre>
<p>接下来就是实现认证这一步，我采用的是实现ICallbackEventHandler接口来进行无刷新操作。<br />
先看很简单的js代码</p>
<pre class="brush: jscript; title: ; notranslate">
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
var accessMessage = document.getElementById('AccessMessage');
function Check()
{
accessMessage.style.display='block';
var pwd = '';
var panel = document.getElementById('AccessPassword_&amp;lt;%=Post.PostIdentity %&amp;gt;');  //DOM找到密码输入框
if(panel) {
pwd = panel.value;
}
if(pwd==''){
accessMessage.innerHTML='密码不能为空';
panel.focus();
return false;
}
accessMessage.innerHTML='正在验证......';
&amp;lt;%= Page.ClientScript.GetCallbackEventReference(this,&amp;quot;pwd&amp;quot;,&amp;quot;checkCallback&amp;quot;,&amp;quot;&amp;quot;)%&amp;gt;;
}

function checkCallback(rValue) {
if(rValue=='error')
{
accessMessage.style.display='block';
accessMessage.innerHTML='密码认证失败';
setTimeout(function(){accessMessage.style.display='none';},2000);
}
else{
accessMessage.style.display='block';
accessMessage.innerHTML='验证成功';
setTimeout(function(){document.getElementById('entrybody_&amp;lt;%=Post.PostIdentity %&amp;gt;').innerHTML = rValue;},500);
setTimeout(function(){accessMessage.style.display='none';},3000);
}
}
function ServerError(error) {
alert(error);
}
&amp;lt;/script&amp;gt;
</pre>
<p>.cs文件中的关于ICallbackEventHandler接口的实现</p>
<pre class="brush: csharp; title: ; notranslate">
#region ICallbackEventHandler 成员
protected string _callback = string.Empty;
string ICallbackEventHandler.GetCallbackResult()
{
return _callback;
}

void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
{
if (Post.AccessPassword == eventArgument.Trim())
{
string SessionKey = &amp;quot;POSTACCESS_&amp;quot; + Post.Id;
HttpContext.Current.Session.Add(SessionKey, true);  //注意这里，当密码验证成功后写session
string path = Utils.RelativeWebRoot + &amp;quot;themes/&amp;quot; + BlogSettings.Instance.Theme + &amp;quot;/PostView.ascx&amp;quot;;

PostViewBase postView = (PostViewBase)LoadControl(path);
postView.Post = Post;
postView.Location = ServingLocation.SinglePost;
_callback = postView.Body;   //此处仍然会执行Post.Serving 事件，但因为前面已经写入了Session，所以触发Post.Serving 事件时将直接返回日志内容。
//因为我想每次访问日志都需要输密码，所以，当正确返回日志内容后，清除掉该Session
HttpContext.Current.Session.Remove(SessionKey);
}
else
{
_callback = &amp;quot;error&amp;quot;;
}
}

#endregion
</pre>
<p>OK，整个过程就是如此，很是简单吧。<br />
同样的原理，可以实现类似于论坛的“回复后可见”同样的功能，如果想长时间维持日志的正常查看权，可将Session换成Cookie。<br />
<span style="color: red;">另外，BlogEngine默认在web.config中将enableSessionState设为了false，请一定要设为true,否则无法使用Session!</span><br />
我就是没有认真看web.config，在Session的获取上大费周折。</p>
]]></content:encoded>
			<wfw:commentRss>http://yibin.us/archives/6036/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>密码保护：测试加密日志</title>
		<link>http://yibin.us/archives/6035</link>
		<comments>http://yibin.us/archives/6035#comments</comments>
		<pubDate>Sat, 25 Oct 2008 06:47:31 +0000</pubDate>
		<dc:creator>幻想曲</dc:creator>
				<category><![CDATA[Asp.Net]]></category>
		<category><![CDATA[blogengine]]></category>

		<guid isPermaLink="false">http://yibin.us/?p=6035</guid>
		<description><![CDATA[无法提供摘要。这是一篇受保护的文章。]]></description>
			<content:encoded><![CDATA[<form action="http://yibin.us/wp-pass.php" method="post">
<p>这是一篇受密码保护的文章。您需要提供访问密码：</p>
<p><label for="pwbox-6035">密码：<br />
<input name="post_password" id="pwbox-6035" type="password" size="20" /></label><br />
<input type="submit" name="Submit" value="提交" /></p></form>
]]></content:encoded>
			<wfw:commentRss>http://yibin.us/archives/6035/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>ImageCropper For .Net</title>
		<link>http://yibin.us/archives/6033</link>
		<comments>http://yibin.us/archives/6033#comments</comments>
		<pubDate>Mon, 20 Oct 2008 03:24:07 +0000</pubDate>
		<dc:creator>幻想曲</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[Asp.Net]]></category>

		<guid isPermaLink="false">http://yibin.us/?p=6033</guid>
		<description><![CDATA[这是一个基于.Net的图片裁剪控件，使用比较广泛，如Gravatar中的头像上传与裁剪功能的实现。当然Gravatar并不是用的这个控件。今天在codeproject中无意发现的，觉得不错，拿来与大家分享一下。 裁剪后基本参数：MaintainAspectRatio，bool型，是否固定宽高比例进行裁剪。CroppedImageHeight，int型，裁剪后的图片高CroppedImageWidth，int型，裁剪后的图片宽JpegQuality，int型，裁剪后的图片质量裁剪时直接调用ImageCropper的Crop()方法即可。 下载地址：http://www.uushare.com/user/yibin/file/899549]]></description>
			<content:encoded><![CDATA[<p>这是一个基于.Net的图片裁剪控件，使用比较广泛，如<a href="http://www.gravatar.com/" target="_blank">Gravatar</a>中的头像上传与裁剪功能的实现。<br />当然<a href="http://www.gravatar.com/" target="_blank">Gravatar</a>并不是用的这个控件。<br />今天在codeproject中无意发现的，觉得不错，拿来与大家分享一下。</p>
<p><a href="http://yibin.us/wp-content/uploads/20081020/00000000097.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20081020/00000000097.png" class="img"  /></a><br />裁剪后<br /><a href="http://yibin.us/wp-content/uploads/20081020/00000000098.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20081020/00000000098.png" class="img"  /></a><br />基本参数：<br /><b>MaintainAspectRatio</b>，bool型，是否固定宽高比例进行裁剪。<br /><b>CroppedImageHeight</b>，int型，裁剪后的图片高<br /><b>CroppedImageWidth</b>，int型，裁剪后的图片宽<br /><b>JpegQuality</b>，int型，裁剪后的图片质量<br />裁剪时直接调用ImageCropper的Crop()方法即可。</p>
<p>下载地址：<br /><a href="http://www.uushare.com/user/yibin/file/899549" target="_blank">http://www.uushare.com/user/yibin/file/899549</a></p>
]]></content:encoded>
			<wfw:commentRss>http://yibin.us/archives/6033/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>让.Net验证控件与自定义验证合作无间</title>
		<link>http://yibin.us/archives/6030</link>
		<comments>http://yibin.us/archives/6030#comments</comments>
		<pubDate>Thu, 16 Oct 2008 06:33:03 +0000</pubDate>
		<dc:creator>幻想曲</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[Asp.Net]]></category>

		<guid isPermaLink="false">http://yibin.us/?p=6030</guid>
		<description><![CDATA[场景： 一个注册表单，其间有.Net自带的验证控件，但有一些验证必须得借助于另外的一些js,如验证是否复选了注册协议(这里为了说明，只举这样一个简单的例子)。这样的话，会涉及到二次验证，第一次可能是.Net验证控件的验证，第二次会认证用户有没有复选注册协议，如何让这二者合作无间呢?这里不得不提到.Net的Page_ClientValidate()函数，该函数返回当前Page页中的表单有没有通过Validate的验证. 新建一个Page页面，简单的放一些控件 &#60;asp:TextBox ID="TextBox1" runat="server"&#62;&#60;/asp:TextBox&#62; &#60;asp:Button ID="Button1" runat="server" Text="Button" ValidationGroup="submit" CausesValidation="True" onclick="Button1_Click" /&#62; &#60;input type="checkbox" id="checkbox" /&#62;我已阅读注册协议 &#60;asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="TextBox1" Display="Dynamic" ErrorMessage="不能为空" ValidationGroup="submit"&#62;&#60;/asp:RequiredFieldValidator&#62; 页面呈现TextBox留空，点击Button,会进行一次验证，当在TextBox中输入文本时，再点击提交，验证通过，引发OnClick事件，但用户是否复选了注册协议此处还未做判断。此时需要我们手写验证函数了 &#60;script type="text/javascript"&#62; function test() { var isCheck = document.getElementById('checkbox').checked; if (isCheck) { //Page_ClientValidate('submit'),这里有不同的ValidGroup,所以Page_ClientValidate传递是指定的GroupName if (Page_ClientValidate('submit')) { alert('验证成功'); return true; } } else { alert('您必须同意注册协议'); return false; } return false; [...]]]></description>
			<content:encoded><![CDATA[<p>场景：<br />  一个注册表单，其间有.Net自带的验证控件，但有一些验证必须得借助于另外的一些js,如验证是否复选了注册协议(这里为了说明，只举这样一个简单的例子)。<br />这样的话，会涉及到二次验证，第一次可能是.Net验证控件的验证，第二次会认证用户有没有复选注册协议，如何让这二者合作无间呢?<br />这里不得不提到.Net的Page_ClientValidate()函数，该函数返回当前Page页中的表单有没有通过Validate的验证.</p>
<p>  新建一个Page页面，简单的放一些控件<br /><code><br />
&lt;asp:TextBox ID="TextBox1" runat="server"&gt;&lt;/asp:TextBox&gt;<br />
        &lt;asp:Button ID="Button1" runat="server"   Text="Button"<br />
            ValidationGroup="submit" CausesValidation="True"<br />
            onclick="Button1_Click" /&gt;<br />
        &lt;input type="checkbox" id="checkbox" /&gt;我已阅读注册协议<br />
        &lt;asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"<br />
            ControlToValidate="TextBox1" Display="Dynamic" ErrorMessage="不能为空"<br />
            ValidationGroup="submit"&gt;&lt;/asp:RequiredFieldValidator&gt;
</pre>
<p>页面呈现<br /><a href="http://yibin.us/wp-content/uploads/20081016/00000000092.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20081016/00000000092.png" class="img"  /></a><br />TextBox留空，点击Button,会进行一次验证，当在TextBox中输入文本时，再点击提交，验证通过，引发OnClick事件，但用户是否复选了注册协议此处还未做判断。<br /><a href="http://yibin.us/wp-content/uploads/20081016/00000000093.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20081016/00000000093.png" class="img"  /></a><br />此时需要我们手写验证函数了<br /><code><br />
&lt;script type="text/javascript"&gt;<br />
        function test() {<br />
            var isCheck = document.getElementById('checkbox').checked;<br />
            if (isCheck) {<br />
	      //Page_ClientValidate('submit'),这里有不同的ValidGroup,所以Page_ClientValidate传递是指定的GroupName<br />
                if (Page_ClientValidate('submit')) {<br />
                    alert('验证成功');<br />
                    return true;<br />
                }<br />
            }<br />
            else {<br />
                alert('您必须同意注册协议');<br />
                return false;<br />
            }</p>
<p>            return false;<br />
        }<br />
    &lt;/script&gt;
</pre>
<p>修改后的代码<br /><code><br />
 &lt;asp:TextBox ID="TextBox1" runat="server"&gt;&lt;/asp:TextBox&gt;<br />
        &lt;asp:Button ID="Button1" runat="server" Text="Button" ValidationGroup="submit" CausesValidation="True"<br />
            OnClientClick="return test();" OnClick="Button1_Click" /&gt;<br />
        &lt;input type="checkbox" id="checkbox" /&gt;我已阅读注册协议<br />
        &lt;asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="TextBox1"<br />
            Display="Dynamic" ErrorMessage="不能为空" ValidationGroup="submit"&gt;&lt;/asp:RequiredFieldValidator&gt;
</pre>
<p>预览页面<br /><a href="http://yibin.us/wp-content/uploads/20081016/00000000094.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20081016/00000000094.png" class="img"  /></a><br /><a href="http://yibin.us/wp-content/uploads/20081016/00000000095.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20081016/00000000095.png" class="img"  /></a><br /><a href="http://yibin.us/wp-content/uploads/20081016/00000000096.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20081016/00000000096.png" class="img"  /></a><br />到这里好像已经结束了，但查看html源代码会发现:<br /><code><br />
&lt;input type="submit" name="Button1" value="Button"<br />
onclick="return test();WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;Button1&quot;, &quot;&quot;, true, &quot;submit&quot;, &quot;&quot;, false, false))" id="Button1" /&gt;
</pre>
<p>Button1除了有return test()外还有WebForm_DoPostBackWithOptions这样一段，很明显WebForm_DoPostBackWithOptions是不会被执行的，去掉这段也很简单，<br />将Button1的CausesValidation设为false即可。</p>
<p>当然，你也可以完全不用验证控件来实现。</p>
]]></content:encoded>
			<wfw:commentRss>http://yibin.us/archives/6030/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>用BeginGetResponse进行异步处理</title>
		<link>http://yibin.us/archives/6025</link>
		<comments>http://yibin.us/archives/6025#comments</comments>
		<pubDate>Fri, 26 Sep 2008 13:20:45 +0000</pubDate>
		<dc:creator>幻想曲</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[Asp.Net]]></category>

		<guid isPermaLink="false">http://yibin.us/?p=6025</guid>
		<description><![CDATA[在今天做的小项目中用户登录成功后要访问另一个应用的一个url，只是get过去。首先想到用HttpWebRequest去直接GetResponse()就OK了但这里会有一个问题：如果另一个应用的响应时间过慢或网络响应过慢，直接会导致登录时会卡一下。可以完全使用HttpWebRequest的异步方法获取响应 class HttpAsynGet { public HttpAsynGet(string url) { this.Url = url; request = (HttpWebRequest)WebRequest.Create(Url); } public string Url { get; set; } private HttpWebRequest request; public HttpWebRequest Request { get { return request; } } public void DO() { request.BeginGetResponse(ProcessResponse, this); } private void ProcessResponse(IAsyncResult ar) { HttpAsynGet item = (HttpAsynGet)ar.AsyncState; using (HttpWebResponse response = [...]]]></description>
			<content:encoded><![CDATA[<p>在今天做的小项目中<br />用户登录成功后要访问另一个应用的一个url，只是get过去。<br />首先想到用HttpWebRequest去直接GetResponse()就OK了<br />但这里会有一个问题：如果另一个应用的响应时间过慢或网络响应过慢，直接会导致登录时会卡一下。<br />可以完全使用HttpWebRequest的异步方法获取响应<br /><code><br />
class HttpAsynGet<br />
    {<br />
        public HttpAsynGet(string url)<br />
        {<br />
            this.Url = url;<br />
            request = (HttpWebRequest)WebRequest.Create(Url);<br />
        }<br />
        public string Url<br />
        {<br />
            get;<br />
            set;<br />
        }<br />
        private HttpWebRequest request;<br />
        public HttpWebRequest Request<br />
        {<br />
            get<br />
            {<br />
                return request;<br />
            }<br />
        }<br />
        public void DO()<br />
        {<br />
            request.BeginGetResponse(ProcessResponse, this);<br />
        }<br />
        private void ProcessResponse(IAsyncResult ar)<br />
        {<br />
            HttpAsynGet item = (HttpAsynGet)ar.AsyncState;<br />
            using (HttpWebResponse response = (HttpWebResponse)item.request.EndGetResponse(ar))<br />
            {<br />
                if (response.StatusCode == HttpStatusCode.OK)<br />
                {<br />
                    Console.WriteLine(response.ContentLength);<br />
                    Console.WriteLine(new string('=', 20));<br />
                }<br />
                else<br />
                {<br />
                    Console.WriteLine(response.StatusDescription);<br />
                }<br />
                this.request.Abort();<br />
            }<br />
        }<br />
    }
</pre>
<p>调用：<br /> HttpAsynGet get = new HttpAsynGet("xxxxxx");<br /> get.DO();<br />即可。<br />在.Net FrameWork的一些类中，只要有以Begin..../End....开头的方法说明该类的这些方法支持异步操作。</p>
]]></content:encoded>
			<wfw:commentRss>http://yibin.us/archives/6025/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>.net中的Provider模式</title>
		<link>http://yibin.us/archives/6024</link>
		<comments>http://yibin.us/archives/6024#comments</comments>
		<pubDate>Tue, 23 Sep 2008 13:19:35 +0000</pubDate>
		<dc:creator>幻想曲</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[Asp.Net]]></category>

		<guid isPermaLink="false">http://yibin.us/?p=6024</guid>
		<description><![CDATA[自.net 2.0出世时，Provider模式就随处可见了，如：MembershipProvider、SiteMapProvider等，它的出现使我们的应用程序有了更大的扩展性，可以是一个数据工厂的提供者，也可以是一个逻辑处理的提供者。而实现这种模式却是相当的简单，只需实现以下四步即可：1、定义一个类，抽象出我们所需要的操作，基类为ProviderBase如: public abstract class RssProvider : ProviderBase { public abstract void LoadRss(); public abstract void AddRss(); } 2、实现一个Section，用来从配置文件中读取Provider的相关配置，该类继承于ConfigurationSection public class RssProviderSection : ConfigurationSection { [ConfigurationProperty("providers")] public ProviderSettingsCollection Providers { get { return (ProviderSettingsCollection)base["providers"]; } set { base["providers"] = value; } } [StringValidator(MinLength=1)] [ConfigurationProperty("defaultProvider", DefaultValue = "XmlProvider")] public string DefaultProvider { get { return (string)base["defaultProvider"]; [...]]]></description>
			<content:encoded><![CDATA[<p>自.net 2.0出世时，Provider模式就随处可见了，如：MembershipProvider、SiteMapProvider等，<br />它的出现使我们的应用程序有了更大的扩展性，可以是一个数据工厂的提供者，也可以是一个逻辑处理的提供者。<br />而实现这种模式却是相当的简单，只需实现以下四步即可：<br />1、定义一个类，抽象出我们所需要的操作，基类为ProviderBase<br />如:<br /><code><br />
public abstract class RssProvider : ProviderBase<br />
    {<br />
        public abstract void LoadRss();<br />
        public abstract void AddRss();<br />
    }
</pre>
<p>2、实现一个Section，用来从配置文件中读取Provider的相关配置，该类继承于ConfigurationSection<br /><code><br />
public class RssProviderSection : ConfigurationSection<br />
    {<br />
        [ConfigurationProperty("providers")]<br />
        public ProviderSettingsCollection Providers<br />
        {<br />
            get { return (ProviderSettingsCollection)base["providers"]; }<br />
            set { base["providers"] = value; }<br />
        }</p>
<p>        [StringValidator(MinLength=1)]<br />
        [ConfigurationProperty("defaultProvider", DefaultValue = "XmlProvider")]<br />
        public string DefaultProvider<br />
        {<br />
            get { return (string)base["defaultProvider"]; }<br />
            set { base["defaultProvider"] = value; }<br />
        }<br />
    }<br />
    public class RssProviderCollection : ProviderCollection<br />
    {<br />
       //从索引器中获取指定名称的Provider<br />
        public new RssProvider this[string name]<br />
        {<br />
            get<br />
            {<br />
                return (RssProvider)base[name];<br />
            }<br />
        }</p>
<p>        public override void Add(ProviderBase provider)<br />
        {<br />
            if (provider == null)<br />
            {<br />
                throw new ArgumentNullException("provider");<br />
            }<br />
            if (provider is RssProvider)<br />
            {<br />
                base.Add(provider);<br />
            }<br />
        }<br />
    }
</pre>
<p>3、在调用时用RssProviderSection去读取配置文件，并加载指定的Provider<br /><code><br />
public class RssService<br />
    {<br />
        private static RssProvider _provider;<br />
        private static RssProviderCollection _providers;<br />
        private static readonly object obj = new object();<br />
        public static RssProvider Provider<br />
        {<br />
            get<br />
            {<br />
                LoadProvider();<br />
                return _provider;<br />
            }<br />
        }<br />
        public static RssProviderCollection Providers<br />
        {</p>
<p>            get {<br />
                LoadProvider();<br />
                return _providers; }<br />
        }</p>
<p>        public static void LoadProvider()<br />
        {<br />
            if (_provider == null)<br />
            {<br />
                lock (obj)<br />
                {<br />
                    if (_provider == null)<br />
                    {<br />
                        RssProviderSection section = (BlogProviderSection)System.Configuration.ConfigurationManager.GetSection("Blog/RssService");<br />
                        _providers = new RssProviderCollection();<br />
                        ProvidersHelper.InstantiateProviders(section.Providers, _providers, typeof(BlogProvider));<br />
                        _provider = _providers[section.DefaultProvider];<br />
                        if (_provider == null)<br />
                            throw new ProviderException("null");<br />
                    }<br />
                }<br />
            }<br />
        }<br />
    }
</pre>
<p>4、配置文件<br /><code><br />
&lt;?xml version="1.0" encoding="utf-8" ?&gt;<br />
&lt;configuration&gt;<br />
  &lt;configSections&gt;<br />
    &lt;sectionGroup name="Blog"&gt;<br />
      &lt;section name="RssService" type="ClassLib.BlogProviderSection,ClassLib"/&gt;<br />
    &lt;/sectionGroup&gt;<br />
  &lt;/configSections&gt;<br />
  &lt;Blog&gt;<br />
    &lt;RssService defaultProvider="XmlProvider"&gt;<br />
      &lt;providers&gt;<br />
        &lt;add name="XmlProvider" type="ClassLib.XmlProvider,ClassLib"&gt;&lt;/add&gt;<br />
        &lt;add name="SqlProvider" type="ClassLib.SqlProvider,ClassLib"&gt;&lt;/add&gt;<br />
      &lt;/providers&gt;<br />
    &lt;/RssService&gt;<br />
  &lt;/Blog&gt;<br />
&lt;/configuration&gt;
</pre>
<p>更多内容可以去MSDN查阅ProviderBase基类</p>
]]></content:encoded>
			<wfw:commentRss>http://yibin.us/archives/6024/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>天气预报控件</title>
		<link>http://yibin.us/archives/6020</link>
		<comments>http://yibin.us/archives/6020#comments</comments>
		<pubDate>Wed, 17 Sep 2008 05:12:33 +0000</pubDate>
		<dc:creator>幻想曲</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[Asp.Net]]></category>

		<guid isPermaLink="false">http://yibin.us/?p=6020</guid>
		<description><![CDATA[数据源取自：http://weather.msn.com/ 原本是打算直接获取页面源代码，然后分析出需要的结果。但这有二个弊端：1、如果页面结构改了，我就得重写代码；2、图片地址要转成绝对路径。不小心让我发现msnweather提供了每个城市的天气预报rss遂直接取rss内容即可。直接将控件放到工具箱， 拖放到.aspx页面上，设置RSS地址即可。rss地址可以到这里来获取：http://weather.msn.com/region.aspx?wealocations=China可以有多个控件，设置不同的rss地址即可显示多个不同城市的天气预报。理论上天气预报会缓存10分钟效果：文件下载：WeatherLib.dll (12.00 kb)]]></description>
			<content:encoded><![CDATA[<p>数据源取自：<a href="http://weather.msn.com/" target="_blank">http://weather.msn.com/</a></p>
<p>原本是打算直接获取页面源代码，然后分析出需要的结果。<br />但这有二个弊端：<br />1、如果页面结构改了，我就得重写代码；<br />2、图片地址要转成绝对路径。<br />不小心让我发现msnweather提供了每个城市的天气预报rss<br />遂直接取rss内容即可。<br />直接将控件放到工具箱， 拖放到.aspx页面上，<font color="Red">设置RSS地址即可</font>。<br />rss地址可以到这里来获取：<br /><a href="http://weather.msn.com/region.aspx?wealocations=China" target="_blank">http://weather.msn.com/region.aspx?wealocations=China</a><br />可以有多个控件，设置不同的rss地址即可显示多个不同城市的天气预报。<br /><font color="Magenta">理论上天气预报会缓存10分钟</font><br />效果：<br /><a href="http://yibin.us/wp-content/uploads/20080917/00000000086.png"  class="thickbox"><img src="http://yibin.us/wp-content/uploads/20080917/00000000086.png" class="img"  /></a><br />文件下载：<br /><a href="http://yibin.us/wp-content/uploads/20080917/WeatherLib.dll" target="_blank" class="download">WeatherLib.dll (12.00 kb)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://yibin.us/archives/6020/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

