本节主要是客串一下飞行事故维护,你说今年西安也是拼了。小区都挂的慢慢的灯笼,网红景点大唐不夜城,南门,曲江池过年肯定是人满为患。不过今年我还是不回家过年,这些地方少不了要去。
这个界面比较加单,这里UI代码我就不贴了,主要看一下切换年份,加载。
this.PropertyChanged += AviationAccident_PropertyChanged; private async void AviationAccident_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == "SelectedYear") { await RefreshUIData(); } } private async Task RefreshUIData() { dataIndex = 0; aviationAccidentList = await this.aviationAccidentFacade.GetAviationAccidentByYear(SelectedYear); if (aviationAccidentList == null || aviationAccidentList.Count == 0) { this.UpdateVisibility = Visibility.Collapsed; this.IsSaveEnabled = true; this.IsRemoveEnabled = false; this.AviationAccidentModel = new AviationAccidentModel(); } else { this.UpdateVisibility = Visibility.Visible; this.IsUpdateEnabled = true; this.IsRemoveEnabled = true; this.IsSaveEnabled = false; this.AviationAccidentModel = AutoMapper.Mapper.Map<AviationAccidentModel>(aviationAccidentList[0]); } this.IsPreviousEnabled = false; this.IsNextEnabled = aviationAccidentList != null && aviationAccidentList.Count > 1; }
我们在ViewModel中,注册一个PropertyChanged事件。当绑定的年份发生变化以后,就会触发propertyChanged事件,在事件中,我们可以判断变化的属性,如果是SelectedYear,则请求WCF Service刷新UI。
public class AviationAccidentFacade : RestClientWrapper { public AviationAccidentFacade(WindowBase windowBase) : base("AviationAccidentWCF", "PhysicalExam", windowBase) { } public async Task<BaseResponse> CreateAviationAccident(AviationAccidentRequest request) { return await this.PostAsync<AviationAccidentRequest, BaseResponse>("create", request); } public async Task<BaseResponse> UpdateAviationAccident(AviationAccidentRequest request) { return await this.PutAsync<AviationAccidentRequest, BaseResponse>("update", request); } public async Task<List<AviationAccidentEntity>> GetAviationAccidentByYear(int year) { return await this.GetAsync<List<AviationAccidentEntity>>(string.Format("get/year/{0}", year)); } public async void DeleteAviationAccident(int year) { await this.DeleteAsync<string>(string.Format("delete/{0}", year)); } }
这个是我们之前提到的facade,继承了一个RestClientWrapper类。我们看一下get就行了,其他代码我不想白给你们看。
protected async Task<T> GetAsync<T>(string relativeUri) { AsyncProgress.GetInstance().ShowPopup(); Uri uri = new Uri(string.Concat(client.BaseAddress.AbsoluteUri, "/", relativeUri)); HttpResponseMessage response = await client.GetAsync(uri, HttpCompletionOption.ResponseContentRead); AsyncProgress.GetInstance().HidePopup(); if (response.IsSuccessStatusCode) { return await response.Content.ReadAsAsync<T>(); } else { return default(T); } }
请求开始的时候,显示进度,请求结束隐藏进度。httpClient类发出请求,获得Response。
ok,我们看一下service端。
其实service端数据访问用EF,我们以刚才的界面get为例子看一下。
[ServiceContract] public interface IAviationAccidentWCF { [OperationContract] [WebInvoke(UriTemplate = "create", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] BaseResponse CreateAviationAccident(AviationAccidentRequest request); [OperationContract] [WebInvoke(UriTemplate = "update", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, Method = "PUT")] BaseResponse UpdateAviationAccident(AviationAccidentRequest request); [OperationContract] [WebGet(UriTemplate = "get/year/{year}", ResponseFormat = WebMessageFormat.Json)] List<AviationAccident> GetAviationAccidentByYear(string year); [OperationContract] [WebInvoke(UriTemplate = "delete/{key}", ResponseFormat = WebMessageFormat.Json, Method = "DELETE")] void DeleteAviationAccident(string key); } public class AviationAccidentWCF : IAviationAccidentWCF { IAviationAccidentService service = new AviationAccidentService(); public BaseResponse CreateAviationAccident(AviationAccidentRequest request) { return service.CreateAviationAccident(request); } public BaseResponse UpdateAviationAccident(AviationAccidentRequest request) { return service.UpdateAviationAccident(request); } public List<AviationAccident> GetAviationAccidentByYear(string year) { return service.GetAviationAccidentByYear(int.Parse(year)); } public void DeleteAviationAccident(string key) { service.DeleteAviationAccident(int.Parse(key)); } }
这个不用我废话,你不懂也没关系,认清Uri就行了。从service下去,就调用到了repository。
public class AviationAccidentRepository : BaseRepository<AviationAccident>, IAviationAccidentRepository { public AviationAccidentRepository(DbContext dbContext) : base(dbContext) { } public AviationAccident GetAviationAccidentByKey(int key) { return this._context.Set<AviationAccident>().FirstOrDefault(f => f.TransactionNumber == key); } public List<AviationAccident> GetAviationAccidentByYear(int year) { return this._context.Set<AviationAccident>().Where(f => f.InDate.Value.Year == year).ToList(); } }
就是这么简单的一个linq查询。
说到最后,要说那个facade的构造函数了,传了三个参数。第一个肯定是WCF Sevice文件名,第二个是文件夹名称
其实搞这个目的是为了不让人很快明白我这个代码的意思,因为源码要给人家的,我自然将代码写的稍稍复杂一些。
不过这几个参数也是为了Uri重写,其实我们请求WCF Service的时候,Uri上不想要.svc,比如AviationAccidentWCF.svc?year={0},我们只想要AviationAccidentWCF?year={0},那么我们就可以进行uri重写。
public class UrlRewriteModule : IHttpModule { public void Dispose() { } public void Init(HttpApplication context) { context.BeginRequest += delegate { HttpContext cxt = HttpContext.Current; string folder = cxt.Request.Headers["Folder"]; string path = string.Concat("~/Services/", folder ?? string.Empty, cxt.Request.CurrentExecutionFilePath); try { int lastIndex = path.LastIndexOf('/'); lastIndex = path.LastIndexOf(folder) + folder.Length + 1; int i = path.IndexOf('/', lastIndex); if (i > 0) { string a = path.Substring(0, i) + ".svc"; string b = path.Substring(i, path.Length - i); string c = cxt.Request.QueryString.ToString(); cxt.RewritePath(a, b, c, false); } } catch { } }; } }
当你不带.svc的请求到达以后,首先由该module处理,他会根据我们传入的uri,构造出真正的uri。比如我们的请求的Uri是http://localhost:59537/AviationAccidentWCF/get/year/2017,那么经过重写以后,就变成http://localhost:59537/AviationAccidentWCF.svc/get/year/2017。
好了,今天就到这里,我要去做饭了,香喷喷的拌汤。说实在的,有点怀念西宁的炕锅羊肉了。
青海人吃饭真的很讲究,还有甘肃人,不管兜里有没有钱,拉面直接加一份牛肉,青海的一个叫同仁县的地方 吃饭也是这样。