none
請教ASP.NET串接API RRS feed

  • 問題

  • 前輩老師好

    之前喵老師曾指導,已經可以建立Server端Web API 可以執行POST、GET、DELETE、PUT等方法

    現在要跟異質系統做串接資料存取

    想請教我要如何將公司的基本資料串接對方的API 將資料傳遞過去? 

    還有串接API跟call對方提供的webservice有什麼不同?

    新增串接的API是要新增專案網站類型,還是主控台? 還是windows form 類型? 謝謝

    2019年10月24日 上午 08:13

解答

  • 用 HttpClient 之類把你的請求傳送過去。

    可參考:https://blog.yowko.com/httpclient/

    開那種專案,答案是都行,看你想用那種專案打過去。


    理直氣和,切記。

    個人

    • 已標示為解答 effor 2019年10月25日 上午 07:35
    2019年10月24日 上午 09:56
  • 1) 如果對方的API接受HTTP協定, 可以利用HttpClient類別叫用API時將資料傳遞過去

    2) 如果對方的API支援HTTP協定, 就和Web Service一樣皆可提供Web服務的功能

    3) 只要能使用HttpClient類別叫用API的專案類型皆可, 包括網站,主控台, 和windows form 類型

    • 已標示為解答 effor 2019年10月25日 上午 07:34
    2019年10月24日 下午 12:59
  • 其實前面就有提到,不要用DataTable
    JSON.NET的JsonConvert.SerializeObject是序列化『物件』,而不是DataTable

    而您的物件,應該是這樣的類別,而不是DataTable

        public class EmpInfo
        {
            public string ID { get; set; } = ""
            public string NAME { get; set; } = ""
            public string DEPARTMENT { get; set; } = ""
            public string TITLE { get; set; } = ""
        }

    (不知道為何您堅持要用DataTable)
    Orz

    兩個方式的建議

    1.透過Dapper for Oracle,直接讀取後把資料放到物件集合(oEmps)
    2.透過迴圈,把DataTable的內容塞到List的EmpInfo物件,成為物件集合(oEmps)

    然後,才是把物件集合,做序列化,產生JSON
    如果您是寫 ASP.NET WebAPI的話
    連序列化的動作都免自己動手,直接Return oEmps;就可以
    (WebAPI會自動的在Return的時候,依據Client端的需求,直接序列化成JSON或者XML)

    小喵個人偏向建議您使用Dapper,用了你會愛上他
    不但程式精簡,而且速度效能也很優

    您可以參考這個

    https://blog.yowko.com/dapper-oracle/


    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...

    • 已標示為解答 effor 2019年11月4日 上午 12:11
    2019年10月30日 上午 06:38
    版主
  • 我在回覆您的時候,您突然刪除了貼文
    我的回覆就貼在您這篇的上面
    把不正確的JSON做字串處理,我不建議這樣做
    正統的做法,WebAPI應該要直接Return oEmps;這樣的方式回傳『物件(或物件集合)』
    也不必自己動手用JSON.NET去序列化

    請您往前看回覆
    動手修改您的WebAPI,並捨棄回傳DataTable的序列化,改回傳『物件(或物件集合)』

    如果您堅持要回傳的是DataTable,那就看有沒有其他有緣人可以幫您了

    ^.^a


    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...


    2019年10月30日 上午 07:25
    版主
  • 1.類別的宣告,不知道您是否有寫在Model裡面

    不建議把東西通通寫在Controller裡面

    Model,Controller各有其應該擔負的責任與職責

    寫在一起當然也是可以執行的出來

    我個人的習慣是
    『物件類別』、『資料存取(Data Access Object,簡稱dao)』,都寫在Models裡面
    Controller就是單純的接Client的Request,呼叫dao,把dao傳回的objects Return

    這部分提供參考

    2.還是推薦您使用Dapper,這是習慣用ADO.NET與SQL語法的人比較容易上手
    (相對換成使用Enterty Framework)
    使用上有很多的好處,至少您不必寫迴圈,在迴圈裡面一個個的欄位要對應屬性一個個的塞入

    當然還有其他好處,不過這細講就是很大的一篇文章了。這裡就提出來帶過~


    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...

    • 已標示為解答 effor 2019年11月4日 上午 12:11
    2019年10月30日 上午 08:18
    版主
  • 先說反序列化的問題

    JSON很簡單,您可能還沒去弄清楚他的一些定義

    {}代表單一物件

    []代表集合(複數、多筆)

    所以單一物件資料就像這樣

    { 
    	"ID": "100384"
    	, "NAME": "林小明"
    	, "DEPARTMENT": "TB20"
    	, "TITLE": "課長" 
    }


    當有多筆的時候就是這樣

    [
    	{ 
    		"ID": "100384"
    		, "NAME": "林小明"
    		, "DEPARTMENT": "TB20"
    		, "TITLE": "課長" 
    	}
    	,{ 
    		"ID": "100385"
    		, "NAME": "陳大華"
    		, "DEPARTMENT": "TB20"
    		, "TITLE": "經理" 
    	}
    ]

    C#單一物件:

    EmpInfo oEmp = new EmpInfo();

    C#物件集合(複數、多筆),用List則是

     List<EmpInfo> oEmps = new List<EmpInfo>();

    您的問題是

    1.你用var(不定型態)的方式去宣告,但是回傳必須是指定型態
    目前的案例,回傳或許可以,如果多筆或無資料時,就可能會出現狀況

    因此,您的WebAPI,在宣告時,建議明確宣告型態,或者最後要轉型態給有指定型態的變數,再回傳指定型態的變數

    詳細,建議您搜尋關鍵字Dapper C#應該可以找到一些訊息

    (這是第一個問題的回覆)

    2.您的第二個問題
    您接收端指定反序列化轉換成多筆,但是取得的JSON卻是單筆

    單筆接單筆,多筆接多筆,就是醬子~喵~

    ^.^a


    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...

    • 已標示為解答 effor 2019年10月31日 上午 06:12
    2019年10月31日 上午 02:17
    版主

所有回覆

  • 用 HttpClient 之類把你的請求傳送過去。

    可參考:https://blog.yowko.com/httpclient/

    開那種專案,答案是都行,看你想用那種專案打過去。


    理直氣和,切記。

    個人

    • 已標示為解答 effor 2019年10月25日 上午 07:35
    2019年10月24日 上午 09:56
  • 1) 如果對方的API接受HTTP協定, 可以利用HttpClient類別叫用API時將資料傳遞過去

    2) 如果對方的API支援HTTP協定, 就和Web Service一樣皆可提供Web服務的功能

    3) 只要能使用HttpClient類別叫用API的專案類型皆可, 包括網站,主控台, 和windows form 類型

    • 已標示為解答 effor 2019年10月25日 上午 07:34
    2019年10月24日 下午 12:59
  • 想請教我要如何將公司的基本資料串接對方的API 將資料傳遞過去?

    如同兩位老師所說,您的程式可以透過HttpClient來進行

    還有串接API跟call對方提供的webservice有什麼不同?
    通常WebService預設就是以xml來進行溝通
    如果要讓WebService使用JSON溝通,就需要額外的一些程式處理
    但ASP.NET WebAPI則是天生預設xml, JSON都可以,只要Client端指定好Content-Type即可
    WebAPI的程式不必特別對xml, json有什麼特別不同的處理

    新增串接的API是要新增專案網站類型,還是主控台? 還是windows form 類型?

    您所說的都行

    只要能夠支援http,無論是什麼類型,甚至電視、手機、手錶、遊戲機、...

    任何IoT裝置,只要能夠能夠連網路且支援http協定,就可以去呼叫使用WebAPI

    ^.^a


    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...

    2019年10月25日 上午 01:49
    版主
  • 謝謝各位老師的回覆

    請問一下,我已經在主控台程式可以呼叫我自己建立的WebAPI

    但如果用windows form 的話,請問怎將responseBody 顯示在文字方塊或datagridview? 

    以及是否可以將回傳的json轉成datatable 顯示在datagridview ? 

    我想要用windows form 方便測試demo,謝謝


      static async void Run()
            {
                using (HttpClient client = new HttpClient())
                {
                    try
                    {
                        client.Timeout = TimeSpan.FromSeconds(30);
                        HttpResponseMessage response = await client.GetAsync(uri);
                        response.EnsureSuccessStatusCode();
                        responseBody = await response.Content.ReadAsStringAsync();
                        result = responseBody.ToString();
                        //Console.WriteLine(responseBody);                                       
                        MessageBox.Show(result);                  
                         
                    }
                    catch (HttpRequestException e)
                    {

                        MessageBox.Show("\nException Caught!");
                        MessageBox.Show("Message :{0} ", e.Message);
                    }
                }
            }

    2019年10月25日 上午 07:31
  • 小喵做的話,不會用『DataTable』

    會先

    1.將對方的JSON,在Visual Studio中,透過選擇性貼上->json轉為類別,變成物件
    2.然後,用JSON的反序列化,將JSON轉成物件的集合
    3.最後,再把物件集合,綁上dataGridView呈現出來

    請參考小喵之前這篇文章

    [筆記]透過 HttpClient 取得政府 Open Data 資料轉成物件集合


    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...

    2019年10月25日 上午 08:39
    版主
  • 喵老師您好

    我執行WebAPI的結果如下,使用chrome

    <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
    [ { "GEN01": "000111", "GEN02": "林小明", "GEN03": "FF20", "GEN04": "課長", "GEN06": null } ]
    </string>

    程式碼如下,

    不知是否回傳的結果不是json格式,所以無法轉datatable 

    不好意思,因為我看不懂您的那個VB語法 

    不知是否可幫忙看一下,謝謝

    var client = new HttpClient();
    client.BaseAddress = new Uri("http://ip/");
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    var response = client.GetAsync("api/emp/000111").Result;
    var body = response.Content.ReadAsStringAsync().Result;

    DataTable dt = JsonConvert.DeserializeObject<DataTable>(body);

    this.dataGridView1.DataSource = dt;

    2019年10月28日 上午 09:41
  • 不好意思,因為我看不懂您的那個VB語法

    這個部分很簡單,您搜尋一下關鍵字『vb.net 2 c#』
    可以找到很多線上工具,可以幫忙把VB.NET的語法翻譯成C#

    語言的部分不該是您找資料、參考資料的障礙

    ^.^a

    -----

    從您貼出來的回傳,對方傳回的似乎是xml包JSON
    但,您說您使用chrome,該不會是直接打網址?
    有使用工具嗎?
    建議您,要測試API,還是要使用一下工具比較好
    推薦使用Chrome的外掛PostMan,或者是Talend API Tester

    這樣要測試get,post,put,delete比較方便,也可以設定Content-Type來處理
    當然也要看對方的API是如何對應,也許有些API只回xml也說不定

    ^.^a

    還有~

    DataTable dt = JsonConvert.DeserializeObject<DataTable>(body);

    我從來沒有說json可以直接反序列化轉DataTable唷
    小喵是請您把對方的JSON,透過選擇性貼上,貼成類別
    然後用『物件集合』的方式來處理

    您這個部分,很肯定一定會不行的。也強烈『不建議』您使用『DataTable』
    您該用的是類別、是物件
    習慣使用物件後,就不會想要再回頭去使用DataTable了

    建議您把小喵那一篇,自己動手做一次,成功了有體悟,再來改成您要的

    您動手試試吧

    ^_^


    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...


    2019年10月28日 上午 10:46
    版主
  • 喵老師您好

    1、我昨天有找的網站都無法轉成C#語法,今天找這個http://converter.telerik.com/ 已OK

    2、測試API如下2個圖,我有用postman 及chrome測試,感覺好像回傳的格式有問題

    3、測試其它政府資料開放平台,已ok了 (如最後圖,不過欄位名稱是中文,所以我類別的欄位也是用成中文?)

    最後是否我自建的webAPI回傳有問題?因為無法轉換成類別物件,謝謝您

     // 宣告HttpClient
                HttpClient client = new HttpClient();
                // 設定連結的網址
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                
    
                string UVUri = "http://datacenter.taichung.gov.tw/swagger/OpenData/1c5e97c9-8232-419b-8109-e3b0ed585676";
                // 取得資料,傳給response(HttpResponseMessage)
                HttpResponseMessage response = client.GetAsync(UVUri).Result;
                // 取得JSON的字串
                string jsonUVs = response.Content.ReadAsStringAsync().Result.ToString();
                // 透過JsonConvert.DeserializeObject 將 JSON字串 轉成物件集合
                List<UVInfo> oUVs = JsonConvert.DeserializeObject<List<UVInfo>>(jsonUVs);
                dataGridView1.DataSource = oUVs;

     public class UVInfo
            {
                public string 區別 { get; set; }
                public string 學校名稱 { get; set; }
                public string 項目 { get; set; }
                public string 是否延長開放 { get; set; }
                public object 上課日 { get; set; }
                public object 國定假日及例假日 { get; set; }
                public object 寒暑假 { get; set; }
                public object 無法調整開放的理由_已配合調整請填0 { get; set; }
                
            }

    2019年10月29日 上午 02:01
  • 2、測試API如下2個圖,我有用postman 及chrome測試,感覺好像回傳的格式有問題

    圖一看起來是正常的
    \r\n只是換行符號

    圖二chrome會一律使用xml處理
    但他回來的資料似乎是JSON

    綜合以上,看起來OK唷

    3、測試其它政府資料開放平台,已ok了 (如最後圖,不過欄位名稱是中文,所以我類別的欄位也是用成中文?)

    從您之前所貼的,他的JSON長這樣

    [ { "GEN01": "000111", "GEN02": "林小明", "GEN03": "FF20", "GEN04": "課長", "GEN06": null } ]

    透過JSON Parser工具整理整理,他會長這樣
    (線上的JSON Parser工具,推薦您使用: http://json.parser.online.fr/

    欄位就是GEN01, GEN02, ...
    哪來的中文
    要也是把這一段JSON,透過『選擇性貼上,貼上JSON成為類別』

    您貼了什麼,為什麼會是中文呢?

    反序列化的時候,會把JSON裡面的變數(欄位)名稱,對應到您的類別中的屬性名稱
    GEN01對GEN01
    GEN02對GEN02

    別亂改他,改了會對照不起來,反序列化當然就會失敗


    至於顯示要有中文標題,在您的顯示上去處理他,例如在GridView中去設定他的Head Text

    資料歸資料、類別歸類別,顯示歸顯示,別混在一起(個人絕少用autogeneratecolumns)

    ^.^a


    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...


    2019年10月29日 上午 03:32
    版主
  • 喵老師您好

    目前已經可以呼叫政府開放資料平台

    http://datacenter.taichung.gov.tw/swagger/OpenData/1c5e97c9-8232-419b-8109-e3b0ed585676(如圖3)

    但是呼叫我自建的API仍有問題(圖1)、回傳的資料格式debug如(圖2)

    定義的類別內容如(圖4) 

    是否可以請您幫忙看一下,謝謝您


    2019年10月29日 上午 06:10
  • 你的類別是自己打的?還是貼選擇性貼上JSON去產生的?

    json的欄位明明就是『GEN01, GEN02, GEN03,...』

    你的類別一個是欄位是『區別,學校名稱,項目,...』

    另一個是『gen01, gen02, gen03』

    兩個都對不上,當然會失敗
    JSON怎麼來,你的類別就要怎麼接?

    這也是VS為了簡化動作,提供了『貼上JSON成為類別』的功能

    很重要,有用了嗎?

    這些在上面這篇已經都說了,有注意到嗎?
    看的時候請看仔細些~
    相同的東西講兩次就有點那個了

    您該有的類別應該是像這樣子

        public class SchoolClassInfo
        {
            public string GEN01 { get; set; } = "";
            public string GEN02 { get; set; } = "";
            public string GEN03 { get; set; } = "";
            public string GEN04 { get; set; } = "";
            public object GEN06 { get; set; } = "";
        }

    另外,既然是自己的API,給的JSON應該改有意義的英文名稱
    不建議用這種順號的
    使用的人會覺得怪

    另外,東拼西湊的學習,會有點似懂非懂
    建議還是找時間把完整的WebAPI, JSON相關的基礎知識作個完整的補強

    加油


    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...



    2019年10月29日 上午 06:42
    版主
  • 喵老師您好

    謝謝您的回覆,

    (你的類別一個是欄位是『區別,學校名稱,項目,另一個是『gen01, gen02, gen03』 )

    因為有呼叫二個API,所以有2個類別 (1個是gen、1個是中文的open-data-臺中市各國小校園開放時間-2.JSON

    那先就以臺中市各國小校園開放時間 http://datacenter.taichung.gov.tw/swagger/OpenData/1c5e97c9-8232-419b-8109-e3b0ed585676 為例

    程式碼及執行結果已OK,已經可以成功呼叫,但呼叫我自行建置的仍是有問題

    就是會出現error converting value '[  的錯誤

    謝謝您的指導


     private void btnJson_Click(object sender, EventArgs e)
            {
                // 宣告HttpClient
                HttpClient client = new HttpClient();
                // 設定連結的網址
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                
    
                string UVUri = "http://datacenter.taichung.gov.tw/swagger/OpenData/1c5e97c9-8232-419b-8109-e3b0ed585676";
                // 取得資料,傳給response(HttpResponseMessage)
                HttpResponseMessage response = client.GetAsync(UVUri).Result;
                // 取得JSON的字串
                string jsonUVs = response.Content.ReadAsStringAsync().Result.ToString();
                // 透過JsonConvert.DeserializeObject 將 JSON字串 轉成物件集合
                List<SchoolInfo> oUVs = JsonConvert.DeserializeObject<List<SchoolInfo>>(jsonUVs);
                dataGridView1.DataSource = oUVs;
            }
     public class SchoolInfo
        {
            public string 區別 { get; set; }
            public string 學校名稱 { get; set; }
            public string 項目 { get; set; }
            public string 是否延長開放 { get; set; }
            public object 上課日 { get; set; }
            public object 國定假日及例假日 { get; set; }
            public object 寒暑假 { get; set; }
            public object 無法調整開放的理由_已配合調整請填0 { get; set; }
        }


    2019年10月29日 上午 07:56
  • 因為有呼叫二個API,所以有2個類別 (1個是gen、1個是中文的open-data-臺中市各國小校園開放時間-2.JSON
    
    那先就以臺中市各國小校園開放時間 http://datacenter.taichung.gov.tw/swagger/OpenData/1c5e97c9-8232-419b-8109-e3b0ed585676 為例
    
    程式碼及執行結果已OK,已經可以成功呼叫,但呼叫我自行建置的仍是有問題

    意思是否是,呼叫學校那個OpenData已經OK
    但是呼叫自己的WebAPI不行?

    已經OK的部分,就先不要貼上來(因為對於我們要協助你的人來說,這是雜訊,是干擾)

    不OK的部分,把『WebAPI取得的JSON內容』與要反序列化『類別的定義』都貼出來

    沒有掌握關鍵的這兩個資料,我只能猜,沒辦法直接點出問題

    通常問題會是在

    1.JSON不標準(可以用JSON Parser檢驗)
    2.JSON與返序列化的類別沒有對應(例如你一直說類別的屬性是小寫gen,但前面看得到的JSON是大寫GEN)


    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...

    2019年10月29日 上午 08:46
    版主
  • JSON應該是

    [ { "ID": "100384", "NAME": "林小明", "DEPARTMENT": "TB20", "TITLE": "課長" } ]

    這樣的文字內容

    不該是

    "[\r\n  {\r\n    \"ID\": \"100384\",\r\n    \"NAME\": \"林小明\",\r\n    \"DEPARTMENT\": \"TB20\",\r\n    \"TITLE\": \"課長\"\r\n  }\r\n]"

    -----

    是否可以請您在

    string jsonUVs = response.Content.ReadAsStringAsync().Result.ToString();


    後面
    把jsonUVs的內容丟到一個TextBox的Text中
    然後把結果的內容丟出來

    我們來看看到底取到的JSON長什麼樣子




    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...

    2019年10月30日 上午 04:14
    版主
  • 其實前面就有提到,不要用DataTable
    JSON.NET的JsonConvert.SerializeObject是序列化『物件』,而不是DataTable

    而您的物件,應該是這樣的類別,而不是DataTable

        public class EmpInfo
        {
            public string ID { get; set; } = ""
            public string NAME { get; set; } = ""
            public string DEPARTMENT { get; set; } = ""
            public string TITLE { get; set; } = ""
        }

    (不知道為何您堅持要用DataTable)
    Orz

    兩個方式的建議

    1.透過Dapper for Oracle,直接讀取後把資料放到物件集合(oEmps)
    2.透過迴圈,把DataTable的內容塞到List的EmpInfo物件,成為物件集合(oEmps)

    然後,才是把物件集合,做序列化,產生JSON
    如果您是寫 ASP.NET WebAPI的話
    連序列化的動作都免自己動手,直接Return oEmps;就可以
    (WebAPI會自動的在Return的時候,依據Client端的需求,直接序列化成JSON或者XML)

    小喵個人偏向建議您使用Dapper,用了你會愛上他
    不但程式精簡,而且速度效能也很優

    您可以參考這個

    https://blog.yowko.com/dapper-oracle/


    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...

    • 已標示為解答 effor 2019年11月4日 上午 12:11
    2019年10月30日 上午 06:38
    版主
  • 我在回覆您的時候,您突然刪除了貼文
    我的回覆就貼在您這篇的上面
    把不正確的JSON做字串處理,我不建議這樣做
    正統的做法,WebAPI應該要直接Return oEmps;這樣的方式回傳『物件(或物件集合)』
    也不必自己動手用JSON.NET去序列化

    請您往前看回覆
    動手修改您的WebAPI,並捨棄回傳DataTable的序列化,改回傳『物件(或物件集合)』

    如果您堅持要回傳的是DataTable,那就看有沒有其他有緣人可以幫您了

    ^.^a


    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...


    2019年10月30日 上午 07:25
    版主

  • 喵老師您好

    了解您的建議及指導,我沒有堅持回傳DataTable喔

    只因為我不知道如何回傳物件(或物件集合) ,真不好意思

    因為我之前學的都是ADO.NET DataTable Dataset 那些...

    請問是否為定義好一個類別跟json回傳的格式欄位一樣如下,然後再將DatatTable的值給它

    剛才有試ok了,我當然是要學習正確好的,謝謝

    請問底下程式有需要修正的嗎? 

     [Route("api/Emp/{id}")]
            [HttpGet]
            public employee GetEmp(string id)
            {
                string str_json = "";
                string sql = "................."          

                DataTable dt = myClass.GetOracleDataSet(sql);
                employee emp = new employee();
                if (dt.Rows.Count > 0)
                {

                    for (int i=0;i<dt.Rows.Count;i++)
                    {
                        emp.ID = dt.Rows[i]["id"].ToString();
                        emp.NAME = dt.Rows[i]["name"].ToString();
                        emp.DEPARTMENT = dt.Rows[i]["department"].ToString();
                        emp.TITLE = dt.Rows[i]["title"].ToString();

                    }                 
                }
                else
                {

                    throw new HttpResponseException(HttpStatusCode.NotFound);
                }

                return emp;
            }

            public class employee
            {
                public string  ID   { get; set; }
                public string  NAME { get; set; }
                public string  DEPARTMENT { get; set; }
                public string  TITLE { get; set; }

            }

                                            
    • 已編輯 effor 2019年10月30日 上午 07:58 update
    2019年10月30日 上午 07:35
  • 1.類別的宣告,不知道您是否有寫在Model裡面

    不建議把東西通通寫在Controller裡面

    Model,Controller各有其應該擔負的責任與職責

    寫在一起當然也是可以執行的出來

    我個人的習慣是
    『物件類別』、『資料存取(Data Access Object,簡稱dao)』,都寫在Models裡面
    Controller就是單純的接Client的Request,呼叫dao,把dao傳回的objects Return

    這部分提供參考

    2.還是推薦您使用Dapper,這是習慣用ADO.NET與SQL語法的人比較容易上手
    (相對換成使用Enterty Framework)
    使用上有很多的好處,至少您不必寫迴圈,在迴圈裡面一個個的欄位要對應屬性一個個的塞入

    當然還有其他好處,不過這細講就是很大的一篇文章了。這裡就提出來帶過~


    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...

    • 已標示為解答 effor 2019年11月4日 上午 12:11
    2019年10月30日 上午 08:18
    版主
  • 您好

    我有將物件類別、資料存取寫在Models裡面,有用dapper語法寫但不知如何return             

    var emp = cn.Query<Models.employee_file>(sql, new { id = "100384" });

    emp 不知如何return 這是第一個問題?

    然後雖然postman測試呼叫回傳的結果是正確的,但我自己寫的程式要去呼叫自建的WebAPI

    執行到這行 List<UVInfo> oUVs = JsonConvert.DeserializeObject<List<UVInfo>>(jsonUVs);     

    仍會出現錯誤訊息,如下圖

    是否可以幫忙查看,謝謝您



    2019年10月31日 上午 12:52
  • 先說反序列化的問題

    JSON很簡單,您可能還沒去弄清楚他的一些定義

    {}代表單一物件

    []代表集合(複數、多筆)

    所以單一物件資料就像這樣

    { 
    	"ID": "100384"
    	, "NAME": "林小明"
    	, "DEPARTMENT": "TB20"
    	, "TITLE": "課長" 
    }


    當有多筆的時候就是這樣

    [
    	{ 
    		"ID": "100384"
    		, "NAME": "林小明"
    		, "DEPARTMENT": "TB20"
    		, "TITLE": "課長" 
    	}
    	,{ 
    		"ID": "100385"
    		, "NAME": "陳大華"
    		, "DEPARTMENT": "TB20"
    		, "TITLE": "經理" 
    	}
    ]

    C#單一物件:

    EmpInfo oEmp = new EmpInfo();

    C#物件集合(複數、多筆),用List則是

     List<EmpInfo> oEmps = new List<EmpInfo>();

    您的問題是

    1.你用var(不定型態)的方式去宣告,但是回傳必須是指定型態
    目前的案例,回傳或許可以,如果多筆或無資料時,就可能會出現狀況

    因此,您的WebAPI,在宣告時,建議明確宣告型態,或者最後要轉型態給有指定型態的變數,再回傳指定型態的變數

    詳細,建議您搜尋關鍵字Dapper C#應該可以找到一些訊息

    (這是第一個問題的回覆)

    2.您的第二個問題
    您接收端指定反序列化轉換成多筆,但是取得的JSON卻是單筆

    單筆接單筆,多筆接多筆,就是醬子~喵~

    ^.^a


    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...

    • 已標示為解答 effor 2019年10月31日 上午 06:12
    2019年10月31日 上午 02:17
    版主
  • 感謝喵老師這期間不厭其煩的回覆說明,謝謝
    2019年11月6日 上午 04:01
  • 最後提醒您

    在ASP.NET中,GridView.DataSource=oUVInfo之後
    還要記得GridView.DataBind()資料才會綁上去,GridView才會顯示出來

    相信Windows Form中的dataGrid應該也是類似的概念

    提供您參考

    ^.^a


    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...

    2019年11月6日 上午 07:21
    版主
  • 謝謝喵老師

    之前多筆已ok,目前這個單筆無法顯示在dataGridView

    後來將oUVinfo 設定到list已經可以了

    不知是否有要改進的地方? 謝謝

     HttpClient client = new HttpClient();
     // 取得資料,傳給response(HttpResponseMessage)
      string UVUri = "http://ip........";
    HttpResponseMessage response = client.GetAsync(UVUri).Result;
      // 取得JSON的字串            
     string jsonUVs = response.Content.ReadAsStringAsync().Result.ToString();
    
     // 透過JsonConvert.DeserializeObject 將 JSON字串 轉成物件集合
               
     UVInfo oUVinfo = JsonConvert.DeserializeObject<UVInfo>(jsonUVs);
    
     List<UVInfo> emplist = new List<UVInfo>()
      {
                    new UVInfo(){ID=oUVinfo.ID,NAMES=oUVinfo.NAMES,DEPARTMENT=oUVinfo.DEPARTMENT,TITLE=oUVinfo.TITLE}
    
       };
    
       dataGridView1.DataSource = emplist;
                

    2019年11月6日 上午 09:01
  • 把單筆加入List,只需要用Add就可以了

    List<UVInfo> emplist = new List<UVInfo>();
    emplist.Add(oUVInfo);

    ^.^a


    topcat(姍舞之間的極度凝聚)
    http://www.dotblogs.com.tw/topcat
    世界上有兩樣東西分享給別人後,不但不會變少,還會變更多:
    一個是快樂,另一個是知識~ 分享...是知識累積的開始...

    2019年11月6日 上午 09:59
    版主
  • 謝謝老師

    了解,已修正ok了,感謝這期間指導.

    2019年11月7日 上午 12:11