2

IISでホストされているWCFRESTfulWebサービスに取り組んでいます。私は現在、かなり単純なPOSTリクエストに取り組んでおり、次のXMLをエンドポイントに送信しています。

<StockListRequestData xmlns="http://myWebService.com/endpoint">
<UserID>2750</UserID>
<StockDatabase>stockLeekRoadVenue</StockDatabase>
<InStockOnly>true</InStockOnly>
</StockListRequestData>

このXMLはDataContract、私のWebサービスのに一致します。

[DataContract(Namespace = "http://myWebService.com/endpoint")]
public class StockListRequestData
{
    [DataMember]
    public string UserID { get; set; }

    [DataMember]
    public string StockDatabase { get; set; }

    [DataMember]
    public bool InStockOnly { get; set; }
}

問題は<InStockOnly>true</InStockOnly>要素です。これをに設定するとtruefalse常に次のように解釈されfalseます...

リクエストを処理するコードは次のとおりです。

public StockListResponseData GetListOfProducts(StockListRequestData requestData)
    {
        var stockList = new StockList(requestData.InStockOnly, requestData.StockDatabase);
        StockListResponseData response;
        if (stockList.Any())
        {
            var stockArray = new Stock[stockList.Count];
            var i = 0;
            foreach (var s in stockList)
            {
                stockArray[i] = s;
                i++;
            }
            response = new StockListResponseData
                           {
                               StockList = stockArray,
                               WasSuccessful = true,
                           };
            return response;
        }
        response = new StockListResponseData
                       {
                           WasSuccessful = false
                       };
        return response;
    }

StockListクラス:

[DataContract]
public class StockList : List<Stock>
{
    public StockList(bool inStockOnly, string stockDb)
    {
        if (inStockOnly)
        {
            // Get only products that are in stock
            var conn = AndyServerDatabase.ConnectToStockMovementByDb(stockDb);
            conn.Open();
            // Compile SQL query
            var q = new SqlCommand(null, conn) { CommandText = "SELECT StockID, Name, PerBox FROM Stock WHERE InStock = 1;" };

            // Execute query
            var rdr = q.ExecuteReader();

            // Check that the output isn't null
            if (rdr.HasRows)
            {
                while(rdr.Read())
                {
                    var id = Convert.ToInt32(rdr[0]);
                    var name = rdr[1].ToString();
                    var perBox = Convert.ToInt32(rdr[2]);
                    Add(new Stock(id, name, perBox));
                }
                conn.Close();
            }
            // Output is null
            conn.Close();
        }
        else
        {
            // Get all products
            // Get only products that are in stock
            var conn = AndyServerDatabase.ConnectToStockMovementByDb(stockDb);
            conn.Open();
            // Compile SQL query
            var q = new SqlCommand(null, conn) { CommandText = "SELECT StockID, Name, PerBox FROM Stock;" };
            q.Prepare();

            // Execute query
            var rdr = q.ExecuteReader();

            // Check that the output isn't null
            if (rdr.HasRows)
            {
                while (rdr.Read())
                {
                    var id = Convert.ToInt32(rdr[0]);
                    var name = rdr[1].ToString();
                    var perBox = Convert.ToInt32(rdr[2]);
                    Add(new Stock(id, name, perBox));
                }
                conn.Close();
            }
            // Output is null
            conn.Close();
        }
        // Add();
    }
}

結果のXML:

<StockListResponseData xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <StockList xmlns:a="http://schemas.datacontract.org/2004/07/SMS">
        <a:Stock>
            <a:Id>1</a:Id>
            <a:Name>Smirnoff Vodka (70cl)</a:Name>
            <a:PerBox>6</a:PerBox>
            <a:Quantity>0</a:Quantity>
            <a:Remains>0</a:Remains>
        </a:Stock>
        <a:Stock>
            <a:Id>2</a:Id>
            <a:Name>Jagermeister (70cl)</a:Name>
            <a:PerBox>6</a:PerBox>
            <a:Quantity>0</a:Quantity>
            <a:Remains>0</a:Remains>
        </a:Stock>
    </StockList>
    <WasSuccessful>true</WasSuccessful>

私はこれが続けるのに十分であることを願っています、私は何年もの間困惑していて、なぜそれがそのように振る舞うのか理解できません..私が含めていない追加のコードが必要な場合はお気軽にお問い合わせください。

どうもありがとう、

アンディ

編集:

何が起こっているかを示すためにいくつかのコンテキストを追加するには:

たとえば、私はそれを知っています:

    <a:Stock>
        <a:Id>2</a:Id>
        <a:Name>Jagermeister (70cl)</a:Name>
        <a:PerBox>6</a:PerBox>
        <a:Quantity>0</a:Quantity>
        <a:Remains>0</a:Remains>
    </a:Stock>

InStockが0に設定されています。これは、を渡した場合、結果のXMLにこれが表示されないことを意味しますtrue

StockListコンストラクターを次のように変更しましif(inStockOnly)if(!inStockOnly)-次に渡し<InStockOnly>true</InStockOnly>ます-StockListコンストラクターに到達すると、反転されて正しいデータが表示されます-したがって、このステートメントに到達するまでにfalseとして読み取られている必要がありますif

私が渡すと<InStockOnly>false</InStockOnly>、それでも「正しい」結果が表示されるため、反転するまでfalseとして読み取られます。

同様に、そのままにしif(inStockOnly)て渡すと、 !<InStockOnly>false</InStockOnly>のデータが表示されます。false

requestData.InStockOnlyStockListResponseData DataContractにも追加しました。そこに、の値をrequestData.InStockOnlyとして出力すると表示されfalseます。

4

2 に答える 2

1

あなたの発見は私を説明に導きました、そしてあなたと同様の問題を抱えている人:

WCF DataContract DataMemberの注文? http://msdn.microsoft.com/en-us/library/ms729813.aspx

次の順序は、DataMemberAttribute属性のOrderプロパティが設定されていない現在のタイプのデータメンバーをアルファベット順に並べたものです。

データメンバーの順序が明示的に指定されていない場合、それらのシリアル化の順序はアルファベット順になります。これが、InStockOnlyが最初にアルファベット順に表示されたため、一番上に移動したときに機能した理由を説明しています。一方、StockDatabaseが機能した理由は、UserIdのアルファベット順であるため、少し謎に包まれています(StockDbがnullの場合、AndyServerDatabase.ConnectToStockMovementByDb()はデフォルト値を使用しますか?)。

議論のために、何らかの理由でそこにある順序を維持したい場合は、次のようにすることができます。

[DataContract(Namespace = "http://myWebService.com/endpoint")]
public class StockListRequestData
{
    [DataMember(Order = 0)]
    public string UserID { get; set; }

    [DataMember(Order = 1)]
    public string StockDatabase { get; set; }

    [DataMember(Order = 2)]
    public bool InStockOnly { get; set; }
}

実際、順序を明示的に示すことはおそらく良い習慣です。そのため、後で新しいプロパティを追加しても何も壊れません。

于 2013-01-06T23:56:01.207 に答える
0

上記の提案を試しましたが、それでも機能しませんでした。検索を続けて別の解決策を見つけ、実際には「指定された」プロパティをtrueに設定しました。

PackageImagesPayload payload = new PackageImagesPayload();
payload.UsesSplitBy = usesSplitBy;
payload.UsesSplitBySpecified = true;
于 2015-07-30T19:32:38.120 に答える