2017年10月21日 星期六

C# HttpClient WebAPI : 6. 使用 POST 要求與 multipart/form-data MIME 類型編碼內容 呼叫 Web API

在這裡,我們來看看另外一種將資料從用戶端傳送到 Web API 伺服器端的方法:multipart/form-data,在這裡,我們需要將要傳送的資料,使用 MIME 格式進行封裝起來,並且透過 POST 的方式傳送到後端 Web API 主機上。這與我們上一篇文章中所用到的 application/x-www-form-urlencoded 方法的差異,在於所將要傳送過去的資料封裝技巧不同,我們可以從原始的 Http 封包內容中,看到兩者的差異。

了解更多關於 [HttpClient Class] 的使用方式
了解更多關於 [使用 async 和 await 進行非同步程式設計] 的使用方式

使用 POST 要求與 multipart/form-data 呼叫 Web API

在這個使用 multipart/form-data 編碼技術要呼叫的 Web API URL 也是 http://vulcanwebapi.azurewebsites.net/api/Values/FormUrlencodedPost,這是因為,後端使用 ASP.NET Core 所開發出來的 Web API,可以同時支援不同編碼技術。
我們建立一個 Dictionary<string, string> 泛型類別物件, formDataDictionary,將要傳送過的欄位名稱與欄位數值,分別加入到這個集合物件內。
我們使用 var content = new MultipartFormDataContent() 敘述,建立一個 content 物件,不過,因為 MultipartFormDataContent 類別以實作 IDisposable 介面,因此,我們使用 using 陳述式將其包起來,讓這個物件於使用完後,可以儘快的釋放掉非受管理的記憶體資源。
這個 MultipartFormDataContent 類別產生的物件,將會用來建立要傳送過去每筆資料紀錄,由於,在這裡我們要傳送過的都是欄位值,所以,我們使用了 StringContent 類別,將要傳送過去的欄位名稱與欄位值建立出來,再加入到 MultipartFormDataContent 集合物件內。
相關資料若都設定完成後,我們就可以呼叫 await client.PostAsync(fooFullUrl, content) 方法,將要傳送過去的資料,使用 multipart/form-data 編碼格式,送到 Web API 主機上對應的控制器與動作方法內。
private static async Task<APIResult> FormDataPostAsync(APIData apiData)
{
    APIResult fooAPIResult;
    using (HttpClientHandler handler = new HttpClientHandler())
    {
        using (HttpClient client = new HttpClient(handler))
        {
            try
            {
                #region 呼叫遠端 Web API
                string FooUrl = $"http://vulcanwebapi.azurewebsites.net/api/Values/FormUrlencodedPost";
                HttpResponseMessage response = null;

                #region  設定相關網址內容
                var fooFullUrl = $"{FooUrl}";

                // Accept 用於宣告客戶端要求服務端回應的文件型態 (底下兩種方法皆可任選其一來使用)
                //client.DefaultRequestHeaders.Accept.TryParseAdd("application/json");
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                // Content-Type 用於宣告遞送給對方的文件型態
                //client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");

                //https://docs.microsoft.com/zh-tw/dotnet/csharp/language-reference/keywords/nameof
                #region 使用 MultipartFormDataContent 產生要 Post 的資料
                // 準備要 Post 的資料
                Dictionary<string, string> formDataDictionary = new Dictionary<string, string>()
                {
                    {nameof(APIData.Id), apiData.Id.ToString() },
                    {nameof(APIData.Name), apiData.Name },
                    {nameof(APIData.Filename), apiData.Filename }
                };

                // https://msdn.microsoft.com/zh-tw/library/system.net.http.multipartformdatacontent(v=vs.110).aspx
                using (var content = new MultipartFormDataContent())
                {
                    foreach (var keyValuePair in formDataDictionary)
                    {
                        content.Add(new StringContent(keyValuePair.Value), keyValuePair.Key);
                    }
                    response = await client.PostAsync(fooFullUrl, content);
                }
                #endregion

                #endregion
                #endregion

                #region 處理呼叫完成 Web API 之後的回報結果
                if (response != null)
                {
                    if (response.IsSuccessStatusCode == true)
                    {
                        // 取得呼叫完成 API 後的回報內容
                        String strResult = await response.Content.ReadAsStringAsync();
                        fooAPIResult = JsonConvert.DeserializeObject<APIResult>(strResult, new JsonSerializerSettings { MetadataPropertyHandling = MetadataPropertyHandling.Ignore });
                    }
                    else
                    {
                        fooAPIResult = new APIResult
                        {
                            Success = false,
                            Message = string.Format("Error Code:{0}, Error Message:{1}", response.StatusCode, response.RequestMessage),
                            Payload = null,
                        };
                    }
                }
                else
                {
                    fooAPIResult = new APIResult
                    {
                        Success = false,
                        Message = "應用程式呼叫 API 發生異常",
                        Payload = null,
                    };
                }
                #endregion
            }
            catch (Exception ex)
            {
                fooAPIResult = new APIResult
                {
                    Success = false,
                    Message = ex.Message,
                    Payload = ex,
                };
            }
        }
    }

    return fooAPIResult;
}

觸發的 Web API 動作

這個範例中,將會指向 URL http://vulcanwebapi.azurewebsites.net/api/Values/FormUrlencodedPost ,此時,將會觸發 Web API 伺服器上的 Values 控制器(Controller)的 public APIResult FormUrlencodedPost([FromForm]APIData value) 動作(Action),其該動作的原始碼如下所示。
這個 Web API 動作,將會回傳一個 APIData 的 JSON 資料。
[HttpPost("FormUrlencodedPost")]
public APIResult FormUrlencodedPost([FromForm]APIData value)
{
    APIResult foo;

    if (value.Id == 777)
    {
        foo = new APIResult()
        {
            Success = true,
            Message = "透過 post 方法,接收到 Id=777 資料",
            Payload = value
        };
    }
    else
    {
        foo = new APIResult()
        {
            Success = false,
            Message = "無法發現到指定的 ID",
            Payload = null
        };
    }
    return foo;
}

進行測試

在程式進入點函式,我們建立一個 APIData 型別的物件,接著,設定該物件的相關屬性,這些屬性值,是我們要傳送到遠端伺服器端的資料,由上面的程式碼中,我們可以知道,當 Id 這個屬性值為 777 的時候,該 Web API 動作將會回覆通知,這次的呼叫是成功的,否則,會回覆此次 Web API 呼叫失敗。
static async Task Main(string[] args)
{
    var fooAPIData = new APIData()
    {
        Id = 777,
        Name = "VulcanSource",
        Filename = "",
    };
    var foo = await FormDataPostAsync(fooAPIData);
    Console.WriteLine($"使用 multipart/form-data MIME 類型編碼 格式與使用 Post 方法呼叫 Web API 的結果");
    Console.WriteLine($"結果狀態 : {foo.Success}");
    Console.WriteLine($"結果訊息 : {foo.Message}");
    Console.WriteLine($"Payload : {foo.Payload}");
    Console.WriteLine($"");

    Console.WriteLine($"Press any key to Exist...{Environment.NewLine}");
    Console.ReadKey();

    fooAPIData = new APIData()
    {
        Id = 123,
        Name = "VulcanSource",
        Filename = "",
    };
    foo = await FormDataPostAsync(fooAPIData);
    Console.WriteLine($"使用 multipart/form-data MIME 類型編碼 格式與使用 Post 方法呼叫 Web API 的結果");
    Console.WriteLine($"結果狀態 : {foo.Success}");
    Console.WriteLine($"結果訊息 : {foo.Message}");
    Console.WriteLine($"Payload : {foo.Payload}");
    Console.WriteLine($"");

    Console.WriteLine($"Press any key to Exist...{Environment.NewLine}");
    Console.ReadKey();
}

執行結果

這個測試將會輸出底下內容
使用 multipart/form-data MIME 類型編碼 格式與使用 Post 方法呼叫 Web API 的結果
結果狀態 : True
結果訊息 : 透過 post 方法,接收到 Id=777 資料
Payload : {
  "id": 777,
  "name": "VulcanSource",
  "filename": null
}

Press any key to Exist...

使用 multipart/form-data MIME 類型編碼 格式與使用 Post 方法呼叫 Web API 的結果
結果狀態 : False
結果訊息 : 無法發現到指定的 ID
Payload :

Press any key to Exist...

HTTP 傳送與接收原始封包

讓我們來看看,這個 Web API 的呼叫動作中,在請求 (Request) 與 反應 (Response) 這兩個階段,會在網路上傳送了那些 HTTP 資料
  • 請求 (Request)
    在底下為原始的 Http 請求封包內容,我們看到了 Content-Type 這個 Http Header 欄位的值設定為 multipart/form-data ,這就表示了這次 POST 要求動作將會是使用 multipart/form-data 編碼方式進行傳送資料;會有這樣的結果產生,那是因為,我們有產生一個 new MultipartFormDataContent()這樣的物件,並且使用 PostAsync 方法,將這個物件傳送到這個非同步方法內。
    而 Content-Length 這個 Http Header 欄位,C# 的 HttpClient 類別,會自動幫我們計算出,此次 Postmultipart/form-data 編碼封包的總共大小。boundary 這個欄位,則是宣告了每個資料的分隔識別代碼是甚麼,這個值,在每次呼叫的時候,都會產生不同的字串出來。
    因此,對於這樣的資料
--8f545aed-8b67-40e7-996c-a357fa37d5a2
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=Id

777
這就表示了,這裡傳送了欄位為 Id (form-data; name=Id),他的數值為 777,並且這個欄位的資料編碼使用的是 text/plain; charset=utf-8
對於完整的 Http multipart/form-data 的封包使用與定義規格,請參考相關說明文件。
POST http://vulcanwebapi.azurewebsites.net/api/Values/FormUrlencodedPost HTTP/1.1
Accept: application/json
Content-Type: multipart/form-data; boundary="8f545aed-8b67-40e7-996c-a357fa37d5a2"
Host: vulcanwebapi.azurewebsites.net
Content-Length: 443
Expect: 100-continue
Connection: Keep-Alive

--8f545aed-8b67-40e7-996c-a357fa37d5a2
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=Id

777
--8f545aed-8b67-40e7-996c-a357fa37d5a2
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=Name

VulcanSource
--8f545aed-8b67-40e7-996c-a357fa37d5a2
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=Filename


--8f545aed-8b67-40e7-996c-a357fa37d5a2--
  • 反應 (Response)
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Server: Kestrel
X-Powered-By: ASP.NET
Set-Cookie: ARRAffinity=9d3635139ab6649f453417d1e9047b7ed7a79b7bef031b04afeb6a2c58b33d4e;Path=/;HttpOnly;Domain=vulcanwebapi.azurewebsites.net
Date: Sat, 21 Oct 2017 10:06:55 GMT

84
{"success":true,"message":"透過 post 方法,接收到 Id=777 資料","payload":{"id":777,"name":"VulcanSource","filename":null}}
0
  • 請求 (Request)
POST http://vulcanwebapi.azurewebsites.net/api/Values/FormUrlencodedPost HTTP/1.1
Accept: application/json
Content-Type: multipart/form-data; boundary="6b46064d-728d-4f76-a0e0-d1c7a2135a85"
Host: vulcanwebapi.azurewebsites.net
Content-Length: 443
Expect: 100-continue

--6b46064d-728d-4f76-a0e0-d1c7a2135a85
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=Id

123
--6b46064d-728d-4f76-a0e0-d1c7a2135a85
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=Name

VulcanSource
--6b46064d-728d-4f76-a0e0-d1c7a2135a85
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=Filename


--6b46064d-728d-4f76-a0e0-d1c7a2135a85--
  • 反應 (Response)
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Server: Kestrel
X-Powered-By: ASP.NET
Set-Cookie: ARRAffinity=9d3635139ab6649f453417d1e9047b7ed7a79b7bef031b04afeb6a2c58b33d4e;Path=/;HttpOnly;Domain=vulcanwebapi.azurewebsites.net
Date: Sat, 21 Oct 2017 10:06:56 GMT

48
{"success":false,"message":"無法發現到指定的 ID","payload":null}
0

相關文章索引

C# HttpClient WebAPI 系列文章索引


了解更多關於 [HttpClient Class] 的使用方式
了解更多關於 [使用 async 和 await 進行非同步程式設計] 的使用方式

關於 Xamarin 在台灣的學習技術資源

Xamarin 實驗室 粉絲團
歡迎加入 Xamarin 實驗室 粉絲團,在這裡,將會經常性的貼出各種關於 Xamarin / Visual Studio / .NET 的相關消息、文章、技術開發等文件,讓您可以隨時掌握第一手的 Xamarin 方面消息。
Xamarin.Forms @ Taiwan
歡迎加入 Xamarin.Forms @ Taiwan,這是台灣的 Xamarin User Group,若您有任何關於 Xamarin / Visual Studio / .NET 上的問題,都可以在這裡來與各方高手來進行討論、交流。
Xamarin 實驗室 部落格
Xamarin 實驗室 部落格 是作者本身的部落格,這個部落格將會專注於 Xamarin 之跨平台 (Android / iOS / UWP) 方面的各類開技術探討、研究與分享的文章,最重要的是,它是全繁體中文。
Xamarin.Forms 系列課程
Xamarin.Forms 系列課程 想要快速進入到 Xamarin.Forms 的開發領域,學會各種 Xamarin.Forms 跨平台開發技術,例如:MVVM、Prism、Data Binding、各種 頁面 Page / 版面配置 Layout / 控制項 Control 的用法等等,千萬不要錯過這些 Xamarin.Forms 課程


2017年10月20日 星期五

VS2017 使用 .NET Core 進行自封式部署 Self-contained deployments (SCD) 發生錯誤

昨天,想要測試一下,剛剛升級好的 Visual Studio 2017 15.4 版本的相關功能,所以,建立了一個 .NET Core 主控台專案,這個專案內並沒有做任何修改,接著,滑鼠右擊該專案,選擇發佈,發現到可以正常發佈;所以,我就修改了該專案的 .csproj 檔案,修改內容如下:
在這裡,我只是增加了 <RuntimeIdentifiers>win10-x64</RuntimeIdentifiers> 這行定義,希望能夠發佈 win10-x64 的 SCD 內容。
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <RuntimeIdentifiers>win10-x64</RuntimeIdentifiers>
  </PropertyGroup>

</Project>
不過,當我進行這個 SCD 發佈的時候,得到底下的錯誤訊息:
最後一行顯示出來的是:無法複製檔案 "obj\Release\netcoreapp2.0\win10-x64\ConsoleApp1.dll",因為找不到檔案 我實際到這個目錄下,真的找不到這個檔案。
正在還原 NuGet 封裝...
為避免 NuGet 在建置期間還原封裝,請開啟 [Visual Studio 選項] 對話方塊,並按一下 [封裝管理員] 節點,然後取消核取 [允許 NuGet 在建置期間下載遺漏的封裝]。
1>------ 已開始建置: 專案: ConsoleApp1, 組態: Release Any CPU ------
1>ConsoleApp1 -> D:\Vulcan\abc\ConsoleApp1\ConsoleApp1\bin\Release\netcoreapp2.0\ConsoleApp1.dll
2>------ 發行已開始: 專案: ConsoleApp1, 組態: Release Any CPU ------
2>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Roslyn\csc.exe /noconfig /unsafe- /checked- /nowarn:1701,1702,1705,1701,1702,2008 /nostdlib+ /platform:x64 /errorreport:prompt /warn:4 /define:TRACE;RELEASE;NETCOREAPP2_0 /errorendlocation /preferreduilang:zh-TW /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\Microsoft.CSharp.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\Microsoft.VisualBasic.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\Microsoft.Win32.Primitives.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\mscorlib.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\netstandard.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.AppContext.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Buffers.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Collections.Concurrent.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Collections.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Collections.Immutable.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Collections.NonGeneric.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Collections.Specialized.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.ComponentModel.Annotations.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.ComponentModel.Composition.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.ComponentModel.DataAnnotations.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.ComponentModel.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.ComponentModel.EventBasedAsync.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.ComponentModel.Primitives.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.ComponentModel.TypeConverter.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Configuration.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Console.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Core.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Data.Common.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Data.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Diagnostics.Contracts.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Diagnostics.Debug.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Diagnostics.DiagnosticSource.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Diagnostics.FileVersionInfo.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Diagnostics.Process.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Diagnostics.StackTrace.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Diagnostics.TextWriterTraceListener.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Diagnostics.Tools.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Diagnostics.TraceSource.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Diagnostics.Tracing.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Drawing.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Drawing.Primitives.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Dynamic.Runtime.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Globalization.Calendars.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Globalization.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Globalization.Extensions.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.IO.Compression.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.IO.Compression.FileSystem.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.IO.Compression.ZipFile.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.IO.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.IO.FileSystem.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.IO.FileSystem.DriveInfo.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.IO.FileSystem.Primitives.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.IO.FileSystem.Watcher.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.IO.IsolatedStorage.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.IO.MemoryMappedFiles.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.IO.Pipes.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.IO.UnmanagedMemoryStream.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Linq.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Linq.Expressions.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Linq.Parallel.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Linq.Queryable.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.Http.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.HttpListener.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.Mail.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.NameResolution.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.NetworkInformation.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.Ping.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.Primitives.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.Requests.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.Security.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.ServicePoint.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.Sockets.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.WebClient.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.WebHeaderCollection.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.WebProxy.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.WebSockets.Client.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Net.WebSockets.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Numerics.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Numerics.Vectors.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.ObjectModel.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Reflection.DispatchProxy.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Reflection.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Reflection.Emit.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Reflection.Emit.ILGeneration.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Reflection.Emit.Lightweight.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Reflection.Extensions.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Reflection.Metadata.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Reflection.Primitives.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Reflection.TypeExtensions.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Resources.Reader.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Resources.ResourceManager.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Resources.Writer.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Runtime.CompilerServices.VisualC.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Runtime.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Runtime.Extensions.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Runtime.Handles.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Runtime.InteropServices.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Runtime.InteropServices.RuntimeInformation.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Runtime.InteropServices.WindowsRuntime.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Runtime.Loader.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Runtime.Numerics.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Runtime.Serialization.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Runtime.Serialization.Formatters.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Runtime.Serialization.Json.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Runtime.Serialization.Primitives.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Runtime.Serialization.Xml.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Security.Claims.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Security.Cryptography.Algorithms.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Security.Cryptography.Csp.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Security.Cryptography.Encoding.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Security.Cryptography.Primitives.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Security.Cryptography.X509Certificates.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Security.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Security.Principal.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Security.SecureString.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.ServiceModel.Web.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.ServiceProcess.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Text.Encoding.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Text.Encoding.Extensions.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Text.RegularExpressions.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Threading.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Threading.Overlapped.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Threading.Tasks.Dataflow.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Threading.Tasks.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Threading.Tasks.Extensions.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Threading.Tasks.Parallel.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Threading.Thread.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Threading.ThreadPool.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Threading.Timer.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Transactions.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Transactions.Local.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.ValueTuple.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Web.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Web.HttpUtility.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Windows.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Xml.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Xml.Linq.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Xml.ReaderWriter.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Xml.Serialization.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Xml.XDocument.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Xml.XmlDocument.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Xml.XmlSerializer.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Xml.XPath.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Xml.XPath.XDocument.dll" /reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\WindowsBase.dll" /debug- /debug:portable /filealign:512 /nologo /optimize+ /out:obj\Release\netcoreapp2.0\win10-x64\ConsoleApp1.dll /ruleset:"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Team Tools\Static Analysis Tools\\Rule Sets\MinimumRecommendedRules.ruleset" /target:exe /warnaserror- /utf8output /deterministic+ Program.cs "C:\Users\vulca\AppData\Local\Temp\.NETCoreApp,Version=v2.0.AssemblyAttributes.cs" obj\Release\netcoreapp2.0\win10-x64\ConsoleApp1.AssemblyInfo.cs /warnaserror+:NU1605
2>無法複製檔案 "obj\Release\netcoreapp2.0\win10-x64\ConsoleApp1.dll",因為找不到檔案。
========== 建置: 1 成功、0 失敗、0 最新、0 略過 ==========
========== 發行: 0 成功、1 失敗、0 略過 ==========
我只好使用 CLI 的方式,嘗試看看是否可以產生 SCD,所以,我進入到這個專案的目錄下,使用底下 CLI 命令:
dotnet publish -c Release -r win10-x64
這是執行結果,真的,真的可以正常執行,產生 SCD 檔案
Microsoft Windows [版本 10.0.16299.19]
(c) 2017 Microsoft Corporation. 著作權所有,並保留一切權利。

D:\Vulcan\abc\ConsoleApp1>dotnet publish -c Release -r win10-x64
Microsoft (R) Build Engine for .NET Core 15.4.8.50001 版
Copyright (C) Microsoft Corporation. 著作權所有,並保留一切權利。

  ConsoleApp1 -> D:\Vulcan\abc\ConsoleApp1\ConsoleApp1\bin\Release\netcoreapp2.0\win10-x64\ConsoleApp1.dll
  ConsoleApp1 -> D:\Vulcan\abc\ConsoleApp1\ConsoleApp1\bin\Release\netcoreapp2.0\win10-x64\publish\

D:\Vulcan\abc\ConsoleApp1>
我實際進入到該專案的 bin\Release\netcoreapp2.0\win10-x64 與 bin\Release\netcoreapp2.0\win10-x64\publish 目錄下,真的有看到實際檔案產生出來。
說實在的,這個時候,我懷疑我的電腦環境是否出了甚麼問題,因此,我進行 Visual Studio 2017 Installer 修補,結果是無效。
此時,沒有辦法的我,只好將 Visual Studio 2017 完全移除,接著安裝今天最新的 Visual Studio 2017 15.4.1 版本,想說,今天又有修版本修正,應該會可以正常運作了吧;結果是,也是無效。
我在開發與測試相關專案的時候,都會使用這個目錄作為 D:\Vulcan\GitBook\Temp 建立專案的跟目錄。
我突然想到,我把專案建立到 C: 磁碟機看看,因此,我在 C 槽建立一個目錄 C:\Vulcan 接著,使用同樣操作方式,建立一個 .NET Core 主控台專案,並且修改 .csproj XML 定義,最後,嘗試使用 SCD 方式來發佈,結果是,一切正常。
我真的太高興了,我連續嘗試在 C:\Vulcan 目錄下,建立兩個目錄 temp 與 You 目錄,但這個時候,我無法在這兩個目錄下產生 SCD 的發佈內容。
我還是不死心,我選擇在 C:\Temp 目錄下,建立專案,結果,還是一樣無法產生 SCD 的發佈內容。
我又回到了 D 槽,嘗試在不同目錄下,建立專案,並且使用 SCD 方式來發佈 .NET Core 專案,得到底下結果。
我不知道發生了甚麼問題,不過,我是有找到一個閃躲解決方案了。
路徑結果
C:\Vulcan\ConsoleApp1* 正常產生 SCD
C:\Vulcan\Temp\ConsoleApp1\ConsoleApp1產生 SCD 失敗
C:\temp\ConsoleApp1產生 SCD 失敗
C:\Vulcan\You\ConsoleApp1產生 SCD 失敗
D:\Vulcan\ConsoleApp1產生 SCD 失敗
D:\Vulcan\GitBook\Temp\ConsoleApp4產生 SCD 失敗
D:\Vulcan\GitBook\ConsoleApp1* 正常產生 SCD
D:\Vulcan\temp\ConsoleApp1* 正常產生 SCD
D:\Vulcan\GitBook\YesYou\ConsoleApp1產生 SCD 失敗
D:\Vulcan\DotTest\DotTest\DotTest\ConsoleApp1產生 SCD 失敗
D:\Vulcan\DotTest\DotTest\ConsoleApp1產生 SCD 失敗
D:\Vulcan\abc\ConsoleApp1產生 SCD 失敗

2017年10月19日 星期四

Visual Studio 2017 元件快取過期(Microsoft.VisualStudio.Web.MicrosoftAzure.AzureFunctions)之問題

昨天,將作業系統升級到 Windows Update 1709 版本,也順便把 Visual Studio 2017 升級到最新 15.4 版本,今天想要建立一個 .NET Core 主控台應用專案,可是,卻得到了這樣的錯誤訊息
Visual Studio 元件快取過期 (組件: Microsoft.VisualStudio.Web.MicrosoftAzure.AzureFunctions, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a),請重新啟動 Visual Studio。
我可以確認的是,昨天之前,這樣的專案類型,是可以成功建立起來的,所以,可能是上述的其中一個升級過程中,發生了問題。
既然是元件快取過期,所以,想說直接把 Visual Studio 元件快取內容,將其清空,所以,安裝了 Clear MEF Component Cache 這個擴充功能,並進行清空 MEF 元件快取,可是,問題並沒有解決掉。
因此,我們再度開啟 Visual Studio 2017,從擴充功能和更新對話窗中,切換到 已安裝的 標籤頁次,搜尋 "Azure Functions" 這個關鍵字,找到 Microsoft Azure WebJobs Tools 這個擴充功能,將其先停用,並且關閉 Visual Studio 2017 與再度開啟 Visual Studio 2017;我們重新建立一個 .NET Core 的主控台專案,發現到竟然可以正常建立這個專案,所以,應該是這個擴充功能發生了問題。
這裡倒是有點奇怪,當我們切換到線上,搜尋這個擴充功能,發現到其名稱不太一樣,在這裡看到的是 Azure Functions and Web Jobs Tools
若我們再度把這個擴充功能啟用,就會發現到,就會依舊無法建立 .NET Core 主控台應用專案。
所以,我們只好把這個擴充功能移除,當我們要移除這個擴充功能,出現底下警告視窗,我們還是繼續進行移除工作。
這個時候,如同對話窗所述,Visual Studio 2017 Installer 就啟動了,開始移除相關元件
從 Visual Studio 2017 Installer 的工作負載中,看到 Azure 開發已經被取消安裝了。
當然,若你開啟 Visual Studio 2017 是可以正常建立 .NET Core 主控台應用專案。
最後,若您還是需要用到 Azure 開發功能,可以從 Visual Studio 2017 Installer 中,將其安裝回來。