Magicshui's Blog

Magicshui on Programming && Life

Keep it simpple

现在我的座右铭又多了一句:Keep it simple搜狗截图_2011-05-07_22-18-18

没有任何东西会是完美的,所以不能做的完整就尝试把它做的简单

MVC3中条件过滤

如果你想添加一些在特定条件下才会执行的过滤器,是不是很酷,但是怎么来进行呢?例如,假设你希images望将认证过滤器设置到除了用户登陆的的所有action上,看起来是个好主意吧?

现在让我们把它实现把,如果你添加一个过滤器到ClobalFilters.Filters集合中,他将会设置到所有的action中,这是一种方式,现在我们期望的是把它添加到除了某一个特定action之上时,这就会出问题了。幸运的是,MVC带有一种新的特性,我们可以写一个类来作为action过滤器来使用。本例,我们需要写一个条件动作控制器。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

public class ConditionalFilterProvider : IFilterProvider {
  private readonly
    IEnumerable> _conditions;

  public ConditionalFilterProvider(
    IEnumerable> conditions)
  {

      _conditions = conditions;
  }

  public IEnumerable GetFilters(
      ControllerContext controllerContext,
      ActionDescriptor actionDescriptor) {
    return from condition in _conditions
           select condition(controllerContext, actionDescriptor) into filter
           where filter != null
           select new Filter(filter, FilterScope.Global, null);
  }
}

然后我们就可以这样使用:

IEnumerable> conditions =
    new Func[] { 

    (c, a) => c.Controller.GetType() != typeof(HomeController) ?
      new MyFilter() : null,
    (c, a) => a.ActionName.StartsWith("About") ? new SomeFilter() : null
};

var provider = new ConditionalFilterProvider(conditions);
FilterProviders.Providers.Add(provider);

详细可以看英文原文

关于异步

其实是自己一直避开的一个技术问题,就像线程一样,但是因为在写比赛项目的手机客户端就不得不面对搜狗截图_2011-04-22_23-59-09这个问题,因为需要使用我们的第三方接口来进行认证用户登陆,而且是需要使用POST进行,在WP7下有两种方式支持网络请求:webclient和webrequest,这里,webclient是比较简单的,但是有一点不太明白就是只知道get方式,而post不知道方法,后来求解得出结论是使用什么什么(忘记名字里,哎,Live writer中没有智能提示呀),而后者又比较麻烦,但是你可以较自由的定制。不管怎样异步是不能少的,估计微软也是为了用户体验的需要,及时你设置了超时,用户也是伤不起的~

这里就说下关于WP7中异步的实现方案:

private void LoadMe()
        {
            IsolatedStorageSettings setting = IsolatedStorageSettings.ApplicationSettings;
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost:13829/client/User/index?id=" + setting["token"]);
            req.Method = "POST";
            UpdateState State = new UpdateState();
            State.AsyncRequest = req;
            req.BeginGetResponse(new AsyncCallback(AnaRepUser), State);

        }

        public class UpdateState
        {
            public HttpWebRequest AsyncRequest { get; set; }
            public HttpWebResponse AsyncResponse { get; set; }
        }
        private void AnaRep(IAsyncResult asyncResult)
        {
            UpdateState myState = (UpdateState)asyncResult.AsyncState;
            HttpWebRequest myRequest = (HttpWebRequest)myState.AsyncRequest;
            //结束异步请求
            myState.AsyncResponse = (HttpWebResponse)myRequest.EndGetResponse(asyncResult);
            Stream streamResult = myState.AsyncResponse.GetResponseStream();
            DoTaskV2.WP7.DoTaskAnalytics ana = new DoTaskAnalytics();
             StreamReader sr = new StreamReader(streamResult);
            string xx= sr.ReadToEnd();
            try
            {
                DoTaskV2.ClientLibiary.ErrorViewModels err = ana.ErrorMessage(xx);
                if (err.id != "00") { this.Dispatcher.BeginInvoke(() => { MessageBox.Show(err.message); }); }

            }
            catch
            {
                List err = ana.AnaTask(xx);

                this.Dispatcher.BeginInvoke(() =>
                {
                    this.g1.DataContext = err;
                });
            }

        }

这里,其实让自己比较不爽的就是在异步以后,你需要调用当前的dispacher来进行设置,否者就是跨线程调用对象,这是不允许的~这里的匿名方法自然少不了~

问题解决后就开始抱怨:

1 异步执行你不知道结果什么时候返回,以前的过程式编程方式需要进行比较大的修改。

2 异步其实就是多一个线程来执行,这样必然造成异步以后的线程间传递数据问题。

但是异步帮助我们解决了界面假死问题,让程序更流程这是毋庸置疑的~

其实,对异步微软的Asyn发布的CTP貌似做了一些改进,可惜以前同时安装MVC3和Asyn以后VS就会出问题,不知道微软把这个小bug解决没~

额,突然想到了一种异步的解决方式,试下~结果以后告知