2013-07-12 3 views
2

Я использую клиента WebApi для публикации в тестовом проекте WebApi. Мой метод почты на моем контроллере принимает единственный параметр (модель).Проводка сложных типов с помощью клиента WebApi

Если я отправляю сообщение с помощью 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; 
 

Единственная разница между 2 вызовами является то, что в одном я звоню PostAsXmlAsync, а в другом, я звоню PostAsJsonAsync.

Вот сиг для моего контроллера (я использую маршрутизации на основе действий)

 

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

// and here's my test model: 
public class Loan 
{ 
    public int LoanId {get;set;} 
} 

// and here's my routing: 
config.Routes.MapHttpRoute(
    name: "DefaultApi", 
    routeTemplate: "api/{controller}/{action}/{id}", 
    defaults: new { action = "get", id = RouteParameter.Optional } 
 

ответ

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> 

Пространство имен в запросе должно совпадать с именем класса вы используете в параметре действия, для 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, и вы будете иметь последовательность в пространствах имен таким образом.

+1

Это отличная догадка и какая ошибка! Я знаю лучше, когда я работаю с WCF, но я не считаю, что webapi использует сериализатор Datacontract под обложками, поэтому, конечно, пространство имен имеет значение! Благодарю. – JMarsch

Смежные вопросы