2014-09-22 88 views
0

首先,我使用C#4.0作爲我的編碼語言。我相信我看到了一些答案,4.5中已經介紹了一些方法,可以使這個方法變得更容易,但是我不需要改變框架。從代碼和網站調用Web API

我正在創建一個MVC4 WebApi,它將被兩個網站和C#代碼(在另一個項目中)使用。從JavaScript調用這個通常情況下,我會做它像這樣:

$.ajax({ 
    dataType: 'text', 
    url: '//localhost:56814/corporations/1/divisions', 
    type: 'POST', 
    data: {"Divisions":[{"Name":"In Store"},{"Name":"Online"}]} 
}).done(function (msg) { 
    alert(msg); 
}).fail(function (jqXHR, textStatus) { 
    alert('Request failed: ' + textStatus); 
}); 

然後在我的服務器端代碼,我只是有我的模型參數:

[HttpPost] 
public HttpResponseMessage Divisions(int id, DivisionCollectionModel model) { 

} 

這一模式將是這樣定義:

public class DivisionCollectionModel { 
    public IEnumerable<DivisionModel> Divisions { get; set; } 
} 

public class DivisionModel { 
    public string Name { get; set; } 
} 

現在,當我試圖測試調用從我的代碼,我能找到讓調用工作的唯一方法這個方法是這樣的:

public static void TestWebApiPost() { 
    var divs = new DivisionCollectionModel { 
     Divisions = new DivisionModel[] { 
      new DivisionModel { 
       Name = "In Store" 
      }, 
      new DivisionModel { 
       Name = "Online" 
      } 
     } 
    }; 

    using (var client = new HttpClient()) { 
     var content = JsonConvert.SerializeObject(divs); 
     var response = client.PostAsync("http://localhost:56814/corporations/1/divisions", new StringContent(content)).Result; 
     Console.WriteLine(response.ToString()); 
    } 
} 

不幸的是,這是無法找到的URL,因爲我的消息的內容是一個字符串,而不是對象。

有沒有辦法,我錯過這裏我是如何發送數據超過,讓我送它作爲一個對象,而不是一個字符串的方法的調用,或HttpContent版本?

我修改了API方法上面接受HttpRequestMessage作爲第二個參數,搞清楚這將允許我使用request.Content.ReadAsStringAsync().Result擺脫請求的對象。這對於從C#客戶端調用它非常有用。然而,當我嘗試使用JavaScript對象調用它,我得到了以下爲我Result

"Divisions%5B0%5D%5BName%5D=In+Store&Divisions%5B1%5D%5BName%5D=Online" 

我試圖運行,通過System.Web.HttpUtility.HtmlDecode()System.Net.WebUtility.HtmlDecode(),但都沒有做任何改變對字符串進行編碼。

更新 我意識到寫完後,我試圖轉換的字符串是一個Url,而不是一個Html字符串。然後我用System.Web.HttpUtility.UrlDecode()試過了,這給了我這樣的:

"Divisions[0][Name]=In Store&Divisions[1][Name]=Online" 

不幸的是,試圖通過Newtonsoft.Json.JsonConvert.DeserializeObject<DivisionCollectionModel>()運行它時也會引發異常。

更清晰的問題集 我認爲,這將是更好的解決辦法,該呼叫從C#客戶端進行,這樣我就不必解析HttpRequestMessage,並允許控制器做「重擔「對我來說。但是,如果沒有辦法通過C#4.0中的object而不是string發送我的數據,那麼最簡單的解決方案就是讓JavaScript客戶端通過字符串而不是對象發送。

我在C#客戶端代碼中丟失了什麼嗎?

+0

您沒有提供JavaScript客戶端的代碼。 – mason 2014-09-22 13:12:21

+0

爲了響應您的更新代碼,您無法反序列化'Divisions [0] [Name] =在Store&Divisions [1] [Name] = Online'中使用Json.NET,因爲這不是有效的JSON。如果你想讓服務器返回JSON,那麼在你的請求頭中設置'accept'值爲'application/json'。 – mason 2014-09-22 13:24:15

+0

我更新了JavaScript以將它作爲accept參數傳遞,但它並未改變如何從'HttpRequestMessage'中取出對象。我會再次更新一個更清晰的問題。 – krillgar 2014-09-22 13:29:21

回答

1

好了,我發現我是用C#客戶端缺少4.0讓這個送過來的JSON對象。這是更新的客戶端:

public static void TestWebApiPost() { 
    var divs = new DivisionCollectionModel { 
     Divisions = new DivisionModel[] { 
      new DivisionModel { 
       Name = "In Store" 
      }, 
      new DivisionModel { 
       Name = "Online" 
      } 
     } 
    }; 

    using (var client = new HttpClient()) { 
     var content = JsonConvert.SerializeObject(divs); 
     var response = client.PostAsync("http://localhost:56814/corporations/1/divisions", 
       new StringContent(content, Encoding.UTF8, "application/json")).Result; 
     Console.WriteLine(response.ToString()); 
    } 
} 

使用StringContent超載,在編碼添加和媒體類型都有它送過來的JSON對象。通過這些更改,您現在可以成功使用WebApi操作方法中只需要模型的相同參數簽名。

1

更改AJAX數據類型 數據類型:「JSON」,

+0

不幸的是,這並沒有幫助。我認爲攻擊這個問題的更好方法是嘗試修復C#代碼試圖與API交流的方式。 – krillgar 2014-09-22 14:12:54