讓大家知道如何使用 asp dot net core 做後臺,使用 UWP 或 WPF 等做前臺。
本文因為沒有什麼業務,也不想做管理系統,所以看到起來是很簡單
VisualStudio
建議去官網下載最新的在線安裝,然後安裝,安裝的時候需要選擇通用平臺開發、桌面開發、跨平臺開發。如果你安裝的不是中文版,請看下面圖片找到差不多的位置,或者全部打勾。
點擊安裝,可以去睡覺,明天再看我的博客。因為 VisualStudio 的安裝是很慢的,如果發現因為自己的網站無法訪問,需要代理,可以發郵件給我,我發一個代理給你。
創建項目
現在一起創建三個項目,第一個項目是 UWP 項目,沒有什麼需要注意,點擊創建空白UWP項目就可以。第二個是一個 dotnet standard 項目。第三個是 dotnet core 項目。
UWP
創建一個 UWP 程序是非常簡單,點擊C#,創建空白項目,隨意給個名字,點擊確定。注意儘量選擇最高的平臺,在項目開發是需要通過用戶才知道需要選哪個平臺。但是在開始學的時候,請儘量選擇最新版本,這樣可以減少因為版本問題讓自己的時間花費在解決版本問題不兼容
如果完全沒有開發過 UWP 程序,那麼請看win10 uwp 如何開始寫 uwp 程序 - CSDN博客
dotnet standard
創建一個 dotnet standard 可以讓多個項目使用,在這裡放一些類的定義。這個項目叫 Model ,名字不是隨便叫的。
dotnet core
右擊解決方案,選擇新建項目,在彈出的窗口選擇 dotnet core ,選擇 asp.net core web 程序。
隨意給這個項目一個名字,然後點擊確定
在彈出的窗口選擇 API ,注意不勾選 Docker 支持
現在就創建好了所有項目
引用項目
現在在創建好的 UWP 項目和 asp dotnet core 項目,右擊引用,加上 Model 的引用
在 UWP 項目,引用的叫引用,在 asp dotnet core 項目,引用叫依賴項,只需要右擊項目,點擊添加就可以看到引用
現在使用新的 VisualStudio 打開相同的解決方案,這樣才可以進行調試 asp dotnet core 的同時調試 UWP 項目
創建通用結構
現在打開 Model 項目,創建一個類,這個類是通用結構,在多個項目都需要使用。現在決定做這個項目是讀取現有的小夥伴的網站和名字,添加新的名字和網站記錄。
那麼這裡的類就需要包含小夥伴的名字和他的網站
public class RoqawzemJajene { public int Id { get; set; } public string Name { get; set; } public string Url { get; set; } }12345678
可以看到上面的代碼多了一個屬性 Id ,現在我還不告訴大家為什麼需要添加 id ,請在看到本文之後,自己嘗試刪除 id 然後重新運行項目。
設置控制器
現在打開 asp dotnet core 項目,通過 RoqawzemJajene 添加控制器。控制器就是訪問 URL 時可以返回結果的類。通過控制器才可以使用 URL 訪問,當然使用其他的方法也是可以做到,但是沒有這個方法好用。
右擊 Controler 添加,點擊添加控制器
選擇EF的控制器,請看下面圖片。使用這個控制器,就會自動下載 EF 而且幫你設置好很多類,最簡單的方法是這樣寫。如果想知道具體的每個類意思就需要自己去看文檔,推薦ASP.NET Core 中文文檔目錄
這時需要告訴 VisualStudio 使用哪個模型類,和上下文,實際上如果剛才的引用已經寫好,而且有 RoqawzemJajene 那麼這一步是十分簡單的。如果沒有按照上面的方法來,那麼這一步可能就無法繼續。本文下面的也就無法繼續。如果實在不知道怎麼弄,歡迎在評論告訴我。
點擊下拉,可以找到 RoqawzemJajene 這個類
點擊了之後會看到沒有數據上下文,點擊最後的加號就可以自動幫你弄好
現在可以看到和下圖差不多的界面,點擊添加就可以等著 VisualStudio 幫你添加一些項目了
現在 VisualStudio 會幫你創建兩個類
public class TopetowLallteContext : DbContext { public TopetowLallteContext (DbContextOptionsoptions) : base(options) { } public DbSet RoqawzemJajene { get; set; } }123456789 [Produces("application/json")] [Route("api/RoqawzemJajenes")] public class RoqawzemJajenesController : Controller { private readonly TopetowLallteContext _context; public RoqawzemJajenesController(TopetowLallteContext context) { _context = context; } // GET: api/RoqawzemJajenes [HttpGet] public IEnumerable GetRoqawzemJajene() { return _context.RoqawzemJajene; } // GET: api/RoqawzemJajenes/5 [HttpGet("{id}")] public async Task GetRoqawzemJajene([FromRoute] int id) { if (!ModelState.IsValid) { return BadRequest(ModelState); } var roqawzemJajene = await _context.RoqawzemJajene.SingleOrDefaultAsync(m => m.Id == id); if (roqawzemJajene == null) { return NotFound(); } return Ok(roqawzemJajene); } // PUT: api/RoqawzemJajenes/5 [HttpPut("{id}")] public async Task PutRoqawzemJajene([FromRoute] int id, [FromBody] RoqawzemJajene roqawzemJajene) { if (!ModelState.IsValid) { return BadRequest(ModelState); } if (id != roqawzemJajene.Id) { return BadRequest(); } _context.Entry(roqawzemJajene).State = EntityState.Modified; try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!RoqawzemJajeneExists(id)) { return NotFound(); } else { throw; } } return NoContent(); } // POST: api/RoqawzemJajenes [HttpPost] public async Task PostRoqawzemJajene([FromBody] RoqawzemJajene roqawzemJajene) { if (!ModelState.IsValid) { return BadRequest(ModelState); } _context.RoqawzemJajene.Add(roqawzemJajene); await _context.SaveChangesAsync(); return CreatedAtAction("GetRoqawzemJajene", new { id = roqawzemJajene.Id }, roqawzemJajene); } // DELETE: api/RoqawzemJajenes/5 [HttpDelete("{id}")] public async Task DeleteRoqawzemJajene([FromRoute] int id) { if (!ModelState.IsValid) { return BadRequest(ModelState); } var roqawzemJajene = await _context.RoqawzemJajene.SingleOrDefaultAsync(m => m.Id == id); if (roqawzemJajene == null) { return NotFound(); } _context.RoqawzemJajene.Remove(roqawzemJajene); await _context.SaveChangesAsync(); return Ok(roqawzemJajene); } private bool RoqawzemJajeneExists(int id) { return _context.RoqawzemJajene.Any(e => e.Id == id); } }123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
請看上圖 RoqawzemJajenesController 就是控制器,TopetowLallteContext 就是數據,裡面包含了數據定義。現代的程序員是很少寫古老的 sql ,因為很難維護,而且容易寫錯。只需要直接對DbSet
因為 asp dotnet core 默認的數據庫是 sql server ,如果直接運行項目會說沒有找到數據庫,所以本文告訴大家使用內存做數據庫。
打開 Startup.cs 找到 ConfigureServices ,可以看到下面代碼
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("TopetowLallteContext"))); }1234567
這裡 UseSqlServer 就是使用 sql server 數據庫,把他修改為options.UseInMemoryDatabase("lindexi")請看代碼
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddDbContext(options => options.UseInMemoryDatabase("lindexi")); }1234567
這時就可以使用內存放數據,當然這時如果關閉了應用,數據也會沒了。
現在打開 RoqawzemJajenesController 構造函數,在第一次進入添加一些數據
public RoqawzemJajenesController(TopetowLallteContext context) { _context = context; if (!context.RoqawzemJajene.Any()) { context.RoqawzemJajene.Add(new RoqawzemJajene() { Name = "lindexi", Url = "https://lindexi.oschina.io" }); context.SaveChanges(); } }1234567891011121314
在這裡添加修改列表都需要調用 context.SaveChanges() 保存
運行網站
先右擊 asp dotnet core 項目屬性,點擊調試,可以看到下面界面
因為不需要使用瀏覽器,所以去掉啟動瀏覽器。需要記下端口,這個端口在下面的 UWP 項目使用。
請看上圖,我的應用 URL 裡面包含了端口 64043
http://localhost:64043/1
現在右擊設置 asp dotnet core 項目為啟動項目,然後按下 F5 運行這個項目
UWP 連接
打開 UWP 程序,先創建一個 ViewModel 用於數據綁定。本文不會告訴大家很多關於 ViewModel 的方法,如果想了解這個寫法,請看win10 uwp MVVM入門
ViewModel
現在需要定義一個數據結構,ObservableCollection 的列表,這樣可以在界面綁定
public class ViewModel { public ObservableCollectionRoqawzemJajeneList { get; set; } = new ObservableCollection (); }12345
綁定數據
界面綁定,首先需要添加 ViewModel 屬性,打開 MainPage.xaml.cs 添加下面代碼
public MainPage() { this.InitializeComponent(); DataContext = ViewModel; } public ViewModel ViewModel { get; } = new ViewModel();1234567
界面
然後在 MainPage.xaml 添加一個列表,在這個 ListView 可以用來顯示列表
12345678910111213141516171819202122232425262728
因為使用了 DataType ,所以需要添加引用
xmlns:model="using:Model"12
因為現在添加了一個按鈕下載數據,所以需要打開 MainPage.xaml.cs 添加下面代碼
private void Button_OnClick(object sender, RoutedEventArgs e) { // 更新數據 }1234
現在的 UWP 軟件是可以編譯通過的,但是運行是不會顯示內容
下載列表
在 MainPage.xaml.cs 的 Button_OnClick 調用 ViewModel 的函數用來更新數據
private void Button_OnClick(object sender, RoutedEventArgs e) { ViewModel.Update(); }1234
這時可能會覺得這樣寫不好,因為有 x:bind 可以在 xaml 綁定 ViewModel 的方法為什麼還需要添加在按鈕。因為這樣寫我可以在按鈕點擊下去同時做一些動畫。
現在打開 ViewModel 先添加引用
using System.Net.Http;12
然後打開 Update 函數,訪問 URL 需要用到 HttpClient,還記得剛才的 RoqawzemJajenesController 裡面有這樣的代碼
[Route("api/RoqawzemJajenes")] public class RoqawzemJajenesController : Controller12
這裡的 Route 就是路由,也就是在 URL 後面添加 api/RoqawzemJajenes 就可以訪問這個控制器。默認的 Get 方法就是通過 GetRoqawzemJajene 實現。
[HttpGet] public IEnumerableGetRoqawzemJajene() { return _context.RoqawzemJajene; }12345
所以想調用 GetRoqawzemJajene 方法就需要訪問 http://localhost:64043/api/RoqawzemJajenes,需要知道,這裡的鏈接的端口是需要在上面右擊 asp dotnet core 項目屬性,調試那裡才知道。
因為 asp dotnet core 程序返回的是 json ,可以通過設置讓他返回 xml 。因為剛才沒設置,默認返回的格式是 json 。
為了解析數據,需要在 Nuget 安裝 json ,打開 Nuget 安裝第一個就可以
通過簡單的 Get 的方法訪問 URL 可以使用下面代碼,參見 win10 UWP GET Post - CSDN博客
public async Task Update() { var httpClient = new HttpClient(); var url = "http://localhost:64043/"; url = url + "api/RoqawzemJajenes"; var str = await httpClient.GetStringAsync(url); var roqawzemJajeneList = JsonConvert.DeserializeObject>(str); RoqawzemJajeneList.Clear(); foreach (var temp in roqawzemJajeneList) { RoqawzemJajeneList.Add(temp); } }12345678910111213141516
上面的代碼通過 Get 訪問 URL 拿到數據只需要一句話
var str = await httpClient.GetStringAsync(url);12
因為這裡使用了異步,所以修改了方法,需要在 MainPage.xaml.cs 的 Button_OnClick 修改
private async void Button_OnClick(object sender, RoutedEventArgs e) { await ViewModel.Update(); }1234
現在嘗試運行 asp dotnet core 項目,然後再運行 UWP 項目,這時點擊一下 UWP 項目的下載數據,就可以看到如下圖界面
現在就完成了 UWP 程序的連接
上傳數據
現在嘗試上傳數據,因為寫界面速度比較慢,所以直接添加一個按鈕,裡面把我的一個小夥伴的信息傳上去。
雖然剛才的代碼已經有一個函數可以用來上傳數據
public async TaskPostRoqawzemJajene([FromBody] RoqawzemJajene roqawzemJajene)1
但是為了讓大家知道如何使用路由,所以修改一下這個參數。
我希望訪問 http://localhost:64043/api/RoqawzemJajenes/add 來添加一個小夥伴。
這時可以在 PostRoqawzemJajene 添加特性。打開 RoqawzemJajenesController ,進入 PostRoqawzemJajene ,在函數上面添加下面代碼
[Route("add")] [HttpPost] public async TaskPostRoqawzemJajene([FromBody] RoqawzemJajene roqawzemJajene)123
現在打開 ViewModel 添加一個函數
public async Task Add() { var roqawzemJajene = new RoqawzemJajene() { Name = "頭像", Url = "https://huangtengxiao.gitee.io/" }; var url = Url + "api/RoqawzemJajenes/add"; var httpClient = new HttpClient(); var str = JsonConvert.SerializeObject(roqawzemJajene); var stringContent = new StringContent(str); stringContent.Headers.ContentType.MediaType = "application/json"; await httpClient.PostAsync(url, stringContent); }12345678910111213141516171819
這裡的 Url 是因為在很多函數都需要使用,所以我把 http://localhost:64043/ 拿出來。在 UWP 使用 post 是很簡單,只需要一句代碼
await httpClient.PostAsync(url, stringContent);12
現在打開 MainPage.xaml 添加一個按鈕
12
然後打開 MainPage.xaml.cs 添加函數
private async void Add_OnClick(object sender, RoutedEventArgs e) { await ViewModel.Add(); await ViewModel.Update(); }12345
現在嘗試運行 UWP 程序,然後點擊上傳,可以看到這個界面
如果剛才的代碼有地方沒有寫對,如 stringContent 沒有添加下面代碼
stringContent.Headers.ContentType.MediaType = "application/json";1
或者寫的 Url 不對,都可以在 asp dotnet core 項目的輸出看到和下面差不多的輸出
Application Insights Telemetry (unconfigured): {"name":"Microsoft.ApplicationInsights.Dev.Message","time":"2018-06-03T07:31:44.4397220Z","tags":{"ai.application.ver":"1.0.0.0","ai.operation.id":"d8ff58c-4a3bece1b1751287","ai.location.ip":"127.0.0.1","ai.internal.nodeName":"DESKTOP-KA1CD6M","ai.operation.name":"POST /api/add","ai.cloud.roleInstance":"DESKTOP-KA1CD6M","ai.internal.sdkVersion":"aspnet5c:2.1.1","ai.operation.parentId":"|d8ff58c-4a3bece1b1751287."},"data":{"baseType":"MessageData","baseData":{"ver":2,"message":"Request starting HTTP/1.1 POST http://localhost:64043/api/add 0","severityLevel":"Information","properties":{"CategoryName":"Microsoft.AspNetCore.Hosting.Internal.WebHost","Scheme":"http","Method":"POST","Host":"localhost:64043","ContentLength":"0","Path":"/api/add","Protocol":"HTTP/1.1","AspNetCoreEnvironment":"Development","DeveloperMode":"true"}}}}Application Insights Telemetry (unconfigured): {"name":"Microsoft.ApplicationInsights.Dev.Message","time":"2018-06-03T07:31:44.4417985Z","tags":{"ai.application.ver":"1.0.0.0","ai.operation.id":"d8ff58c-4a3bece1b1751287","ai.location.ip":"127.0.0.1","ai.internal.nodeName":"DESKTOP-KA1CD6M","ai.operation.name":"POST /api/add","ai.cloud.roleInstance":"DESKTOP-KA1CD6M","ai.internal.sdkVersion":"aspnet5c:2.1.1","ai.operation.parentId":"|d8ff58c-4a3bece1b1751287."},"data":{"baseType":"MessageData","baseData":{"ver":2,"message":"Request finished in 2.0912ms 404","severityLevel":"Information","properties":{"CategoryName":"Microsoft.AspNetCore.Hosting.Internal.WebHost","StatusCode":"404","ElapsedMilliseconds":"2.0912","AspNetCoreEnvironment":"Development","DeveloperMode":"true"}}}}Application Insights Telemetry (unconfigured): {"name":"Microsoft.ApplicationInsights.Dev.Request","time":"2018-06-03T07:31:44.4395938Z","tags":{"ai.location.ip":"127.0.0.1","ai.cloud.roleInstance":"DESKTOP-KA1CD6M","ai.internal.nodeName":"DESKTOP-KA1CD6M","ai.operation.id":"d8ff58c-4a3bece1b1751287","ai.internal.sdkVersion":"aspnet5c:2.1.1","ai.operation.name":"POST /api/add","ai.application.ver":"1.0.0.0"},"data":{"baseType":"RequestData","baseData":{"ver":2,"id":"|d8ff58c-4a3bece1b1751287.","name":"POST /api/add","duration":"00:00:00.0045034","success":false,"responseCode":"404","url":"http://localhost:64043/api/add","properties":{"httpMethod":"POST","AspNetCoreEnvironment":"Development","DeveloperMode":"true"}}}}1234
在這裡,如何寫一個簡單的 cs 程序已經告訴了大家,建議完全複製代碼來試試。如果發現還是無法運行,看到的界面和我不一樣。那麼嘗試下載我的代碼來試試。
如果遇到任何問題歡迎通過評論告訴我,或發郵件給我。
代碼:手把手教你使用 asp dotnet core 做 cs 程序 1.1-CSDN下載
我搭建了自己的博客 https://lindexi.gitee.io/ 歡迎大家訪問,裡面有很多新的博客。只有在我看到博客寫成熟之後才會放在csdn或博客園,但是一旦發佈了就不再更新
閱讀更多 程序員小新人學習 的文章