将图像插入Azure blob - {“错误:内部服务器错误”} MobileInvalidOperationException

时间:2013-06-15 21:02:34

标签: azure azure-storage azure-mobile-services

我正在尝试将Win 8应用程序中的图像插入Azure blob。当我尝试执行此操作时,我遇到了500异常。这是我正在使用的课程 -

private MobileServiceCollection<TodoItem, TodoItem> items;
        private IMobileServiceTable<TodoItem> todoTable = App.MobileService.GetTable<TodoItem>();

   [DataContract]
    public class TodoItem
        {

        [DataMember(Name = "id")]
        public int ID { get; set; }

        [DataMember(Name = "text")]
        public string Text { get; set; }



        [DataMember(Name = "containerName")]
        public string ContainerName { get; set; }


        [DataMember(Name = "resourceName")]
        public string ResourceName { get; set; }


        [DataMember(Name = "sasQueryString")]
        public string SasQueryString { get; set; }


        [DataMember(Name = "imageUri")]
        public string ImageUri { get; set; }
        }

在-tait todoTable.InsertAsync(todoItem)行中抛出异常 此时抛出异常,SASQueryString和ImageUri的值为NULL。

        private async void OnTakePhotoClick(object sender, RoutedEventArgs e)
        {
            // Capture a new photo or video from the device.
            CameraCaptureUI cameraCapture = new CameraCaptureUI();
            media = await cameraCapture
                .CaptureFileAsync(CameraCaptureUIMode.PhotoOrVideo);
            TodoItem todoitem = new TodoItem { Text="NA",ContainerName="todoitemimages"};
             InsertTodoItem(todoitem);


        }

private async void InsertTodoItem(TodoItem todoItem)
{
    string errorString = string.Empty;


    if (media != null)
    {
        // Set blob properties of TodoItem.

        todoItem.ResourceName = media.Name;

    }


    // Send the item to be inserted. When blob properties are set this
    // generates an SAS in the response.
    await todoTable.InsertAsync(todoItem);


    // If we have a returned SAS, then upload the blob.
    if (!string.IsNullOrEmpty(todoItem.SasQueryString))
    {
        // Get the new image as a stream.
        using (var fileStream = await media.OpenStreamForReadAsync())
        {
            // Get the URI generated that contains the SAS 
            // and extract the storage credentials.
            StorageCredentials cred = new StorageCredentials(todoItem.SasQueryString);
            var imageUri = new Uri(todoItem.ImageUri);


            // Instantiate a Blob store container based on the info in the returned item.
            CloudBlobContainer container = new CloudBlobContainer(
                new Uri(string.Format("https://{0}/{1}",
                    imageUri.Host, todoItem.ContainerName)), cred);


            // Upload the new image as a BLOB from the stream.
            CloudBlockBlob blobFromSASCredential =
                container.GetBlockBlobReference(todoItem.ResourceName);
            await blobFromSASCredential.UploadFromStreamAsync(fileStream.AsInputStream());
        }
    }


    // Add the new item to the collection.
    items.Add(todoItem);


}

无论如何,我可以解决此异常。谢​​谢。

   These are the exception details -
     

Microsoft.WindowsAzure.MobileServices.MobileServiceInvalidOperationException   未处理HResult = -2146233079消息=错误:内部服务器   错误源= Microsoft.Threading.Tasks StackTrace:          在Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)          在Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(任务   任务)          在Microsoft.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(任务任务)          在Microsoft.Runtime.CompilerServices.TaskAwaiter.GetResult()          在Microsoft.WindowsAzure.MobileServices.MobileServiceTable`1.d_ 0.MoveNext()       ---从抛出异常的先前位置开始的堆栈跟踪结束---          在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)          在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)          在DeltaVMobile.CrudeStorageScenario.d _22.MoveNext()中   C:\用户\〜       ---从抛出异常的先前位置开始的堆栈跟踪结束---          在System.Runtime.CompilerServices.AsyncMethodBuilderCore.b__0(对象   州)          在System.Threading.WinRTSynchronizationContext.Invoker.InvokeCore()       ---从抛出异常的先前位置开始的堆栈跟踪结束---          在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()          在System.Threading.ExecutionContext.RunInternal(ExecutionContext   executionContext,ContextCallback回调,对象状态,布尔值   preserveSyncCtx)          at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean   preserveSyncCtx)          在System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()          在System.Threading.ThreadPoolWorkQueue.Dispatch()InnerException:

1 个答案:

答案 0 :(得分:0)

默认情况下,Azure移动服务启用了“动态模式”,这意味着您不需要在表中定义列 - 只要您插入数据,它就会“找出”相应的类型和为您创建列。但它需要确定使用哪种类型。在您的情况下,这是将发送到服务的请求(为了清楚起见,添加了JSON的漂亮打印,实际上它是在没有不必要的空格的情况下发送的):

POST .../tables/TodoItem
Content-Type: application/json

{
    "text":null,
    "containerName":"todoitemimages",
    "resourceName":null,
    "sasQueryString":null,
    "imageUri":null
}

当它第一次到达服务时,它知道您正在尝试插入诸如“text”,“resourceName”之类的列,但是因为没有与之关联的值(null可以是任何类型),它将无法插入该数据。

如果这确实是你的问题,你基本上有两个选择:一个简单的选择是在开发期间做一个虚拟插入一次,并且所有类型的成员都有一些价值 - 然后马上发出一个删除已插入的项目。这样就可以创建列,之后运行时不必“猜测”它们的类型。另一种选择是将EmitDefaultValue属性中的[DataMember]属性设置为false,这将使序列化程序不使用空值发出请求中的字段。