# Fetch - Call API

## HTTP POST

使用 HTTP POST 傳送 JSON 資料到 Server

```csharp
Fetch f = new Fetch("https://httpbin.org/post");

// 自訂 header
f.Header = new
{
    Access_Token = "123456789"
};

// 自訂 cookie
f.Cookie = new
{
    account = "Gold"
};

// 查詢字串: ?qs=dog
var query_str = new
{
    qs = "dog"
};

// 傳送資料: { id: 100, ... }
var json_data = new
{
    id = 100,
    name = "zap",
    data = new List<object>()
    {
        new { sid=10, name="book" },
        new { sid=10, name="pen" },
    }
};

// 發出請求
string result = f.Post(json_data, query_str);

if (result == null) Console.WriteLine(f.GetResponse());
else Console.WriteLine(result);
```

**輸出：**

```javascript
{
  "args": {
    "qs": "dog"
  }, 
  "data": "{\"id\":100,\"name\":\"zap\",\"data\":[{\"sid\":10,\"name\":\"book\"},{\"sid\":10,\"name\":\"pen\"}]}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Access-Token": "123456789", 
    "Content-Length": "81", 
    "Content-Type": "application/json; charset=utf-8", 
    "Cookie": "account=Gold", 
    "Host": "httpbin.org", 
    "X-Amzn-Trace-Id": "Root=1-5e7ed774-ad2d9263c688cd7cc7198855"
  }, 
  "json": {
    "data": [
      {
        "name": "book", 
        "sid": 10
      }, 
      {
        "name": "pen", 
        "sid": 10
      }
    ], 
    "id": 100, 
    "name": "zap"
  }, 
  "origin": "10.10.10.10", 
  "url": "https://httpbin.org/post?qs=dog"
}
```

## Other HTTP Methods

使用方式與 [HTTP POST](/zaplib2/fetch/fetch-get-json-response.md#http-post) 相似，只需將 Post 方法改為其他即可

```csharp
// 發出 Get 請求
string result = f.Get(json_data, query_str);

// 發出 Delete 請求
string result = f.Delete(json_data, query_str);

// 發出 Put 請求
string result = f.Put(json_data, query_str);

// 發出 Patch 請求
string result = f.Patch(json_data, query_str);
```

## Mapping JSON to Model

Fetch 使用 [Json.NET](https://www.newtonsoft.com/json) 提供的方法，將回應的 JSON 填充到指定物件中

### Declare Data Model

定義一個能夠承接回傳資料的類別，注意 JSON 的 **成員名稱** 與 **資料型態** 需要相同才可正常對應

```csharp
public class ModelResponse
{
    public string origin { get; set; }
    public string url { get; set; }
}
```

{% hint style="info" %}
如果 JSON 的成員名稱無法宣告成 Model，可以使用 [JsonProperty](https://www.newtonsoft.com/json/help/html/JsonPropertyName.htm) 指定命名
{% endhint %}

### Specify The Model

```csharp
Fetch f = new Fetch("https://httpbin.org/put");

ModelResponse result = f.Put<ModelResponse>();

if (result != null)
{
    Console.WriteLine("origin = " + result.origin);
    Console.WriteLine("url = " + result.url);
}
```

**輸出：**

```
origin = 10.10.10.10
url = https://httpbin.org/put
```

## Dynamic Request Configuration

Query String、Cookie 或 Header 不是固定的，都可使用 DynamicObject 類別動態組成

```csharp
// 動態新增成員的物件
DynamicObject dobj = new DynamicObject("MyQs");
dobj.CreateProperty("search_query", typeof(string), "柴犬");
object qs = dobj.CreateObject();

// 發處請求
Fetch f = new Fetch("https://www.youtube.com/results");
string result = f.Get(qs);
Console.WriteLine(result);
```

## Form Data

Fetch 預設 Content-Type 為 `application/json` 資料預設會編碼成 JSON 字串後傳送，但也支援 `application/x-www-form-urlencoded` 與 `multipart/form-data` MIME 編碼方式，只需指定即可

```csharp
Fetch f = new Fetch("https://httpbin.org/put");
// 指定內容 MIME 
f.ContentType = "application/x-www-form-urlencoded";
Console.WriteLine(f.Put(new { id = 100, name = "zap" }));
```

**輸出：**

Server 將接到 Form 編碼的資料

```csharp
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "id": "100", 
    "name": "zap"
  }, 
  "headers": {
    "Content-Length": "15", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "X-Amzn-Trace-Id": "Root=1-5e7ebcc6-df7bf161441274a690e0a4f0"
  }, 
  "json": null, 
  "origin": "10.10.10.10", 
  "url": "https://httpbin.org/put"
}
```

## Attach Files

傳送檔案預設以 `multipart/form-data` 的編碼方式傳送，只需指定檔案實體位置即可

```csharp
Fetch f = new Fetch("https://httpbin.org/post");
var data = new
{
    id = 999,
    name = "zap"
};
var files = new
{
    file1 = Environment.CurrentDirectory + "\\1.png",
    file2 = Environment.CurrentDirectory + "\\2.png"
};
Console.WriteLine(f.Post(data, null, files));
```

**輸出：**

檔案將以 Base64 方式編碼後至於 Form 中傳遞

```javascript
{
  "args": {}, 
  "data": "", 
  "files": {
    "file1": "data:application/octet-stream;base64,iVBORw0KGgoAAAANSUhEUgAA...", 
    "file2": "data:application/octet-stream;base64,iVBORw0KGgoAAAANSUhEUgAA..."
  }, 
  "form": {
    "id": "999", 
    "name": "zap"
  }, 
  "headers": {
    "Content-Length": "62936", 
    "Content-Type": "multipart/form-data; boundary=\"4dfd80e2-b5e2-444b-bd2b-fb50c75b7f14\"", 
    "Host": "httpbin.org", 
    "X-Amzn-Trace-Id": "Root=1-5e7ed5fe-5196074a652ff9ec70d878d1"
  }, 
  "json": null, 
  "origin": "10.10.10.10", 
  "url": "https://httpbin.org/post"
}
```

## Response Header

回應的訊息除了在 body 中，有部分資料也會帶在 header 中

```csharp
Fetch f = new Fetch("https://httpbin.org/get");
if (f.Get() != null)
{
    // 取得指定名稱 Header
    Console.WriteLine("Server : " + f.GetResponseHeader("Server"));
    
    // 取得指定名稱 Header 並自動轉型
    Console.WriteLine("Date : " + f.GetResponseHeader<DateTime>("Date"));
    
    // 取得全部 Header
    Console.WriteLine("\n全部:");
    foreach (var header in f.GetResponseHeaders())
        Console.WriteLine(header.Key + ": " + header.Value.First());
}
```

**輸出：**

```
Server : gunicorn/19.9.0
Date : 1999/3/9 下午 01:01:31

全部:
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Date: Sat, 09 Mar 1999 01:01:31 GMT
Server: gunicorn/19.9.0
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://zaplib.gitbook.io/zaplib2/fetch/fetch-get-json-response.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
