1

次のコードを使用します。

foreach (JObject obj in arr)
{
    id = (string)obj["Id"];
    packSize = (Int16)obj["PackSize"];
    var description = (string)obj["Description"];
    var deptSubdept = (Double)obj["DeptDotSubdept"];
    var unitCost = (Double)obj["Unit_Cost"];
    var unitList = (Double)obj["Unit_List"];
    var UPC_Code = (string)obj["UPC_code"];
    var UPC_packSize = (Int16)obj["UPC_pack_size"];
    var CRVId = (Int32)obj["CRV_Id"];

inventoryItems.Add(new WebAPIClientUtils.InventoryItem
{
    Id = id,
    PackSize = packSize,
    Description = description,
    DeptDotSubdept = deptSubdept,
    Unit_Cost = unitCost,
    Unit_List = unitList,
    UPC_code = UPC_Code,
    UPC_pack_size = UPC_packSize,
    CRV_Id = CRVId
});

...私は、「System.ArgumentException: 入力文字列は正しい形式ではありませんでした。コスト列に <> を格納できませんでした。予想される型は Double です。 ---> System.FormatException...

注: 「Cost」は、次のように定義されたローカル テーブル内の列の名前です。

// Create temp table that mirrors InventoryItems as a staging area for the data to be bulk copied
var dt = new DataTable();
dt.Columns.Add(new DataColumn("Id", typeof(string)));
. . .
dt.Columns.Add(new DataColumn("Cost", typeof(double)));
. . .

取得したデータにこれらの偽/空の値がある場合、どうすればそれを確認し、double の場合は 0.00、int の場合は 0、String の場合は string.empty、&c などの値を使用できますか?

これがいつ発生したかを確認するために、次の行に条件付きブレークポイントを設定しました。

var unitCost = (Double)obj["Unit_Cost"];

...Breakpoint Condition ダイアログに次のように入力します。

unitCost.ToString() == ""

...しかし、決して到達することはありません。また、「 unitCost == null 」を条件付きブレークポイントとして設定しようとしましたが、同じ [非] 結果でした。

アップデート

これとともに:

id = (string)obj["Id"] ?? string.Empty;
packSize = (Int16)obj["PackSize"] ?? 0;
var description = (string)obj["Description"] ?? string.Empty;
var deptSubdept = (Double)obj["DeptDotSubdept"] ?? 0.0;
var unitCost = (Double)obj["Unit_Cost"] ?? 0.0;
var unitList = (Double)obj["Unit_List"] ?? 0.0;
var UPC_Code = (string)obj["UPC_code"] ?? string.Empty;
var UPC_packSize = (Int16)obj["UPC_pack_size"] ?? 0;
var CRVId = (Int32)obj["CRV_Id"] ?? 0;

...私は得る:

演算子「??」タイプ 'short' および 'int' 演算子 '??' のオペランドには適用できません タイプ 'double' および 'double' 演算子 '??' のオペランドには適用できません タイプ「int」および「int」のオペランドには適用できません

更新 2

私はこれを試しました:

double unitCost;
if (obj["Unit_Cost"] != DBNull.Value)
{
    unitCost = (Double) obj["Unit_Cost"];
}
else
{
    unitCost = 0.0;
}

...そして、「演算子 '!=' はタイプ 'Newtonsoft.Json.Linq.JToken' および 'System.DBNull' のオペランドには適用できません

更新 3

次のように、条件付き代入の最初の部分を括弧で囲みます。

var UPC_Code = ((string)obj["UPC_code"]) ?? string.Empty;

...文字列に対してのみ機能します。他のデータ型 (int および double) のエラー メッセージがまだ表示されます。

更新 4

次のコードで実行時例外が発生していました。

dt.Rows.Add(invItem.Id, invItem.PackSize, invItem.Description, invItem.DeptDotSubdept,  
    invItem.Unit_Cost, invItem.Unit_List, invItem.UPC_code, invItem.UPC_pack_size, 
    invItem.CRV_Id);

...だから私はこれを試しました:

int packSize = 1;
double unitCost = 0.0;
double unitList = 0.0;

if (invItem.PackSize != null)
{
    packSize = invItem.PackSize;
}
if (invItem.Unit_Cost != null)
{
    unitCost = invItem.Unit_Cost;
}
if (invItem.Unit_List != null)
{
    unitList = invItem.Unit_List;
}

dt.Rows.Add(invItem.Id, packSize, invItem.Description, 
    invItem.DeptDotSubdept, unitCost, unitList, invItem.UPC_code, 
    invItem.UPC_pack_size, invItem.CRV_Id);

...しかし、それでも失敗し、エディターで「!= null」行に青い波線が表示される場合があります。

更新 5

SLaksの提案に関して、私は試しました:

if (obj["Unit_Cost"] == DBNull.Value)
{
    unitCost = 0.0;
}
else
{
    unitCost = (Double)obj["Unit_Cost"];
}

...しかし、「演算子 '==' はタイプ 'Newtonsoft.Json.Linq.JToken' および 'System.DBNull' のオペランドには適用できません

私はこれで同じことを得る:

if ((Double)obj["Unit_Cost"] == DBNull.Value)

....この:

if (((Double)obj["Unit_Cost"]) == DBNull.Value)

更新 6

これが失敗した場合、unitCost の値は null ではなく 0 であることがわかります。そのため、その値が割り当てられるブレークポイントを設定します。

unitCost == 0

...しかし、値が 0.0 (問題ありません) の場合でも、ブレークポイントにヒットします。0でもいいと思いますが… 失敗しているので、明らかに値に何か問題があります。

4

6 に答える 6

1

DeserializeObjectの代わりにを使用すると、 と を使用JObjectしてこれを非常に簡単に行うことができDefaultValueAttributeますDefaultValueHandling

void Main()
{
    var item = JsonConvert.DeserializeObject<InventoryItem>(@"{""Id"": 1}",
         new JsonSerializerSettings {
                DefaultValueHandling = DefaultValueHandling.Populate });
    // item.PackSize == 1
}
public class InventoryItem
{
    public string Id { get; set; }
    [DefaultValue(1)]
    public Int16 PackSize { get; set; }
    [DefaultValue("")]
    public string Description { get; set; }
    public Double DeptDotSubdept { get; set; }
}
于 2013-11-25T19:32:56.547 に答える
1

この回答と、あなたが持っているタイプに関する最近の情報に基づいて、次のことを試してください。

id = obj.Value<string>("Id") ?? "";
packSize = obj.Value<short?>("PackSize") ?? (short)0;
var description = obj.Value<string>("Description") ?? "";
var deptSubdept = obj.Value<double?>("DeptDotSubdept") ?? 0.0;
var unitCost = obj.Value<double?>("Unit_Cost") ?? 0.0;
...
var crvId = obj.Value<int>("CRV_Id") ?? 0;
于 2013-11-25T21:36:51.577 に答える
1

これを試して

Double dbl;
Int16 int16;
Int32 int32;

    foreach (JObject obj in arr)
    {
        id = (string)obj["Id"];
        packSize = Int16.TryParse(obj["PackSize"].ToString(), out int16) ? (Int16)obj["PackSize"]:0;
        var description = (string)obj["Description"];
        var deptSubdept = Double.TryParse(obj["DeptDotSubdept"].ToString(), out dbl) ? (Double)obj["DeptDotSubdept"] : 0.00;
        var unitCost = Double.TryParse(obj["Unit_Cost"].ToString, out dbl) ? (Double)obj["Unit_Cost"] : 0.00;
        var unitList = Double.TryParse(obj["Unit_List"].ToString(), out dbl) ? (Double)obj["Unit_List"] : 0.00;
        var UPC_Code = (string)obj["UPC_code"];
        var UPC_packSize = Int16.TryParse(obj["UPC_pack_size"].ToString(), out int16) ? (Int16)obj["UPC_pack_size"] : 0;
        var CRVId = Int32.TryParse(obj["CRV_Id"].ToString(), out int32) ? (Int32)obj["CRV_Id"] : 0;

    inventoryItems.Add(new WebAPIClientUtils.InventoryItem
    {
        Id = id,
        PackSize = packSize,
        Description = description,
        DeptDotSubdept = deptSubdept,
        Unit_Cost = unitCost,
        Unit_List = unitList,
        UPC_code = UPC_Code,
        UPC_pack_size = UPC_packSize,
        CRV_Id = CRVId
    })
于 2013-11-25T19:34:10.460 に答える
1

as演算子でnull 許容型に変換してみて、を使用してくださいNullable(T).GetValueOrDefault

foreach (JObject obj in arr)
{
    var id = obj["Id"] as string;
    var packSize = obj["PackSize"] as short?;
    var description = obj["Description"] as string;
    var deptSubdept = obj["DeptDotSubdept"] as double?;
    var unitCost = obj["Unit_Cost"] as decimal?;
    var unitList = obj["Unit_List"] as decimal?;
    var UPC_Code = obj["UPC_code"] as string;
    var UPC_packSize = obj["UPC_pack_size"] as short?;
    var CRVId = obj["CRV_Id"] as int?;

    inventoryItems.Add(new WebAPIClientUtils.InventoryItem
    {
        Id = id ?? string.Empty,
        PackSize = packSize.GetValueOrDefault(),
        Description = description ?? string.Empty,
        DeptDotSubdept = deptSubdept.GetValueOrDefault(),
        Unit_Cost = unitCost.GetValueOrDefault(),
        Unit_List = unitList.GetValueOrDefault(),
        UPC_code = UPC_Code ?? string.Empty,
        UPC_pack_size = UPC_packSize.GetValueOrDefault(),
        CRV_Id = CRVId.GetValueOrDefault()
    });
}

decimal通貨にも使用します。

于 2013-11-25T19:55:41.270 に答える
1

あなたが見ているDBNull.Valueのは、オーバーライドToString()して return""です。

小切手

if (obj["Unit_Cost"] == DBNull.Value)

の場合objは、DataRow呼び出すこともできますobj.IsNull("Unit_Cost")

于 2013-11-25T19:27:00.090 に答える