2

我正在使用 WebApi Client 发布到 WebApi 测试项目。我的控制器上的 post 方法接受单个参数(模型)。

如果我使用 JSON 发布,一切正常。如果我使用 XML 发布,则该参数始终为空。这是一个错误吗?

var client = new HttpClient();
// on the server side, the loan param will be null
var response = client.PostAsXmlAsync(
    "http://localhost.fiddler:54835/api/Loan/PostLoan", 
    new Loan() { LoanId = 1 }).Result;

// on the server side, the loan param is just fine
var response = client.PostAsJsonAsync(
    "http://localhost.fiddler:54835/api/Loan/PostLoan", 
    new Loan() { LoanId = 1 }).Result;

这两个电话之间的唯一区别是,一个是我在打电话PostAsXmlAsync,另一个是我在打电话PostAsJsonAsync

这是我的控制器的信号(我正在使用基于操作的路由):

[HttpPost]
public void PostLoan(Loan loan)
{
    Debug.WriteLine(loan.LoanId);
}

这是我的测试模型:

public class Loan
{
    public int LoanId { get; set; }
}

这是我的路线:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { action = "get", id = RouteParameter.Optional }
4

1 回答 1

3

我的猜测是您在 Web API 和客户端应用程序中使用了单独的类。如果您查看请求 XML,您将看到类似这样的命名空间。我只是MyNamespace用来说明。

<Loan xmlns:i="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns="http://schemas.datacontract.org/2004/07/MyNamespace">
    <LoanId>1</LoanId>
</Loan>

请求中的命名空间必须与您在 action 参数中使用的类匹配,DataContractSerializer才能正常工作。

比如说,您Loan在 Web API 中的类的命名空间为MyWebApiProject.MyModels. 在客户端应用程序中,你的Loan类需要像这样,如果它的命名空间不是MyWebApiProject.MyModels.

[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/MyWebApiProject.MyModels")]
    public class Loan
    {
        [DataMember]
        public int LoanId { get; set; }
    }

如果您想共享 DTO,最好将它们分离到一个项目中并在客户端和 Web API 中引用它们,这样您将在命名空间中保持一致。

于 2013-07-13T03:01:10.317 回答