【问题标题】:Calling Web API from code and website从代码和网站调用 Web API
【发布时间】:2014-11-16 11:20:01
【问题描述】:

首先,我使用 C# 4.0 作为我的编码语言。我相信我看到了一些答案,其中 4.5 引入了一些可以使这变得更容易的方法,但这不是我改变框架的呼吁。

我正在创建一个 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&lt;DivisionCollectionModel&gt;() 运行它时也会引发异常。

更清晰的问题集 我认为最好修复从 C# 客户端进行调用的方式,这样我就不必解析 HttpRequestMessage,并允许控制器为我做“繁重的工作”。但是,如果在 C# 4.0 中无法将我的数据作为 object 而不是 string 发送,那么最简单的解决方案就是让 JavaScript 客户端通过字符串而不是对象发送。

我的 C# 客户端代码中是否缺少某些内容?

【问题讨论】:

  • 您没有提供 JavaScript 客户端的代码。
  • 响应您更新的代码,您无法使用 Json.NET 反序列化 Divisions[0][Name]=In Store&amp;Divisions[1][Name]=Online,因为那不是有效的 JSON。如果您希望服务器返回 JSON,则在您的请求标头中将 accept 值设置为 application/json
  • 我更新了 JavaScript 以将其作为接受参数传递,但它并没有改变从 HttpRequestMessage 中提取对象的方式。我将再次更新一个更清晰的问题。
  • 您正在对您的问题进行大量更新,这使得您似乎发布了一个错误的问题。您的问题应该很清楚,显示所有相关代码并准确解释您的问题。此外,您似乎对服务器和客户端之间的数据交换方式感到困惑。您可以阅读 JSON、XML 等,然后了解您使用的工具在什么时候将它们在格式和原生对象之间转换。
  • 我知道所有这些信息。我知道 MVC 控制器结构如何获取所有这些信息,并将其处理成我在问题中发布的两种类型的 Action 方法签名。

标签: c# javascript asp.net-mvc-4 c#-4.0 asp.net-web-api


【解决方案1】:

更改 ajax 数据类型 数据类型:'json',

【讨论】:

  • 不幸的是,这无济于事。我认为解决这个问题的更好方法是尝试修复 C# 代码尝试与 API 对话的方式。
【解决方案2】:

好的,所以我发现了我在 4.0 中使用 C# 客户端缺少的东西,以便将其作为 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 操作方法中使用仅需要您的模型的相同参数签名。

【讨论】:

    猜你喜欢
    • 2017-02-11
    • 2012-05-05
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多