REST с полиморфными контрактами данных - сбой десериализации - PullRequest
5 голосов
/ 06 октября 2011

Это приводило меня в бешенство весь день, так как я не внес никаких изменений, клянусь, это работало так, как я планировал вчера.

У меня есть служба REST WCF 4, определенная в следующем контракте:

[ServiceContract]
public interface IPhoneFeaturesManagementHost
{
    [OperationContract]
    [WebInvoke(Method = "POST", UriTemplate = "/accounts/{accountNumber}/phoneNumbers/{phoneNumber}/features/{featureType}", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare)]
    void UpdateFeatureStatus(string accountNumber, string phoneNumber, string featureType, FeatureUpdateRequest updateRequest);
}

У меня также определены следующие типы:

[DataContract]
[KnownType(typeof(One900FeatureUpdateRequest))]
public abstract class FeatureUpdateRequest
{
    [DataMember]
    public FeatureStatus Status { get; set; }

    [DataMember]
    public DateTime EffectiveDate { get; set; }

    public string AccountNumber { get; set; }
    public string PhoneNumber { get; set; }
    public string UserId { get; set; }
    public DateTime Timestamp { get; set; }

    public override string ToString()
    {
        return String.Format("Status: {0}, Effective Date: {1}", Status, EffectiveDate);
    }
}

[DataContract]
public class One900FeatureUpdateRequest : FeatureUpdateRequest
{
    [DataMember]
    public bool PerformSwitchUpdate { get; set; }
}

Вчера я клянусь, что смог отправить данные POST этой формы:

<One900FeatureUpdateRequest>
  <EffectiveDate>1999-05-31T11:20:00</EffectiveDate>
  <Status>Enabled</Status>
  <PerformSwitchUpdate>true</PerformSwitchUpdate>
</One900FeatureUpdateRequest>

Сегодня тот же пакет XML вызывает ошибки HTTP 400 со следующим сообщением:

Unable to deserialize XML body with root name 'One900FeatureUpdateRequest' and root namespace '' (for operation 'UpdateFeatureStatus' and contract ('IPhoneFeaturesManagementHost',  'http://tempuri.org/')) using DataContractSerializer. Ensure that the type corresponding to the XML is added to the known types collection of the service.

Единственный XML, который сегодня работает, - это приведенный ниже код, и мне действительно очень не нравится необходимость добавления атрибута namespace plusописать подтип моего дочернего DataContract.

<FeatureUpdateRequest i:type="One900FeatureUpdateRequest" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Project.Services.Host">
  <EffectiveDate>1999-05-31T11:20:00</EffectiveDate>
  <Status>Enabled</Status>
  <PerformSwitchUpdate>true</PerformSwitchUpdate>
</FeatureUpdateRequest>

Есть ли у кого-нибудь какие-либо идеи относительно того, что я мог бы затронуть или что мне, возможно, придется изменить, чтобы вернуться к прежнему простому формату XML для десериализации?

Любая помощь будет высоко ценится.Спасибо!

1 Ответ

1 голос
/ 06 октября 2011

Я не смог найти способ сделать это с помощью DataContractSerializer, поэтому вместо этого я переключился на старый XmlSerializer, чтобы иметь прямой контроль над форматом XML.Казалось, это работает.

...