2014-09-22 69 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