2

問題

WindowsPhone8アプリを持っています。ユーザーはアプリから写真をアップロードし、AzureMobileServiceを使用して処理するためのエントリをテーブルに追加できます。テーブルの列の1つはDeviceIdです。この部分は正常に機能します。

別のビューでは、人々はすでに追加したエントリのリストをロードできます。残念ながら、一部のユーザーにとっては、エントリが返されないため、これは機能しないようです(データベースでエントリを見つけることができます)。

一部のユーザーには機能し、他のユーザーには機能しない理由がわからないので、助けてください。

DeviceUniqueIdを取得する方法は次のとおりです。

byte[] myDeviceID = (byte[])Microsoft.Phone.Info.DeviceExtendedProperties.GetValue("DeviceUniqueId");
string DeviceIDAsString = Convert.ToBase64String(myDeviceID);

新しいエントリを追加する方法は次のとおりです 。TimelapseBatch.DeviceId(コンストラクターの最初のパラメーターは文字列です)

var item = new TimelapseBatch(DeviceInfo.DeviceUniqueId, /*other properties go here*/);
await App.MobileService.GetTable<TimelapseBatch>().InsertAsync(item);

サービスを照会する方法

private readonly IMobileServiceTable<TimelapseBatch> batchesTable = App.MobileService.GetTable<TimelapseBatch>();
...
batches = await batchesTable.Where(t => t.DeviceId == DeviceInfo.DeviceUniqueId).ToListAsync();

var processed = batches.Where(t => t.StatusCode == (int)BatchStatus.Processed).OrderByDescending(t => t.Processed).Select(t => new Timelapse()
{
    Page = new Uri(t.PlayerUrl),
    Thumbnail = new Uri(t.ThumbnailUrl)
}).ToList();

どうやら、データベースによれば、この処理のすべてにエントリが含まれていないようです。

同じユーザー(問題が発生しているユーザーでも)が複数のエントリを作成する場合、データベース内のDeviceIdは同じように見えることを確認しました。

助けてください、なぜそれが一部のユーザーには機能するが他のユーザーには機能しないのですか?

アップデート

そのため、問題が発生したお客様のDeviceUniqueIdを使用すると、問題を再現できます。

また、私がこのようにそれを行う場合:

batches = await batchesTable.Take(200).ToListAsync();
batches = batches.Where(t => t.DeviceId == DeviceInfo.DeviceUniqueId).ToList();

期待どおりにバッチを設定します。ただし、これを行うと(以下)、バッチは空になります(エントリが少ないため、テスト目的で200を指定しました)。

batches = await batchesTable.Take(200).Where(t => t.DeviceId == DeviceInfo.DeviceUniqueId).ToListAsync();

更新2

DeviceIdに「+」記号が含まれている場合、比較は失敗するようです。私が行った場合

t.DeviceId.Substring(0,X) == DeviceInfo.DeviceUniqueId.Substring(0,X)

Xが+記号の位置である場合、期待どおりに機能します。ああ、神様。今、私は必死に回避策を見つけようとしています。

更新3

タイプ定義:

public enum BatchStatus
{
    QueuedUp = 0,
    Processed = 1,
    Error = 2,
}

public class TimelapseBatch
{
    public TimelapseBatch()
    {
        TimelapseId = String.Empty;
        DeviceId = String.Empty;
        ContainerUrl = String.Empty;
        VideoMp4Url = String.Empty;
        VideoWebmUrl = String.Empty;
        ThumbnailUrl = String.Empty;
        Uploaded = new DateTime(2000, 1, 1);
        Processed = new DateTime(2000, 1, 1);
        PlayerUrl = String.Empty;
    }

    public TimelapseBatch(string deviceId, string timelapseId, string containerUrl, int photosCount, int fps):this()
    {
        DeviceId = deviceId;
        ContainerUrl = containerUrl;
        TimelapseId = timelapseId;
        PhotosCount = photosCount;
        Fps = fps;
        StatusCode = (int) BatchStatus.QueuedUp;
        Uploaded = DateTime.Now;
    }

    public int Id { get; set; }
    public int StatusCode { get; set; }

    public string TimelapseId { get; set; }
    public string DeviceId { get; set; }
    public string ContainerUrl { get; set; }
    public int PhotosCount { get; set; }
    public int Fps { get; set; }
    public DateTime Uploaded { get; set; }


    public string VideoMp4Url { get; set; }
    public string VideoWebmUrl { get; set; }
    public string ThumbnailUrl { get; set; }
    public double VideoSize { get; set; }
    public DateTime Processed { get; set; }

    public string PlayerUrl { get; set; }
}
4

1 に答える 1

1

そして今、解決策:

 batches = await batchesTable.Where(t => t.DeviceId == DeviceInfo.DeviceUniqueId.Replace("+", "%2B") || t.DeviceId == DeviceInfo.DeviceUniqueId).ToListAsync();

手動でエスケープして%2Bとして署名する必要がありました。Azureチームがバグを修正する場合に備えて、追加の条件を追加しました。

于 2013-03-27T04:10:34.417 に答える