简体   繁体   English

使用cli和.net在Azure中上传到Blob存储的问题

[英]Problems with uploading to blob storage in azure using a cli and .net

Using c# with the .net framework and microsoft azure and i am trying to upload a file in a cli which should be picked up by a webjob. 将C#与.net框架和Microsoft Azure结合使用,我正在尝试在cli中上传文件,该文件应由webjob进行拾取。 I'm sure the webjob is fine but i am having problems getting upload to work. 我确定webjob很好,但是在上载时遇到了问题。

// Pick URL location of service up from metadata
AudioSamples client = new AudioSamples(new AnonymousCredential());
var id = Console.ReadLine();
Console.WriteLine();

string path = "api/samples/" + id;
Console.WriteLine("Enter the file name.");
string fileName = Console.ReadLine();
using (var stream = File.OpenRead(fileName))
{              
   HttpOperationResponse response = await client.PutAsync(path, new StreamContent(stream));
}

From what i understand the PutAsync should work for streaming the file but it gives me an error saying the command doesn't exist 据我了解,PutAsync应该适用于流式传输文件,但是它给我一个错误,指出该命令不存在

this api should also be used with the upload to a blob but im not sure how it connect it to the client. 此api也应与上传到Blob一起使用,但不确定该如何将其连接到客户端。

namespace AudioSamples.Controllers
{
   [ApiExplorerSettings(IgnoreApi = true)]
   public class DataController : ApiController
   {
      private const String partitionName = "AudioSamples_Partition_1";
      private CloudStorageAccount storageAccount;
      private CloudTableClient tableClient;
      private CloudTable table;
      private BlobStorageService _blobStorageService = new BlobStorageService();
      private CloudQueueService _queueStorageService = new CloudQueueService();

      String name;

      public DataController()
      {
         storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["AzureWebJobsStorage"].ToString());
         tableClient = storageAccount.CreateCloudTableClient();
         table = tableClient.GetTableReference("AudioSamples");
      }

      private void deleteOldBlobs(AudioSampleEntityModel sample)
      {
         CloudBlobContainer blobContainer = _blobStorageService.getCloudBlobContainer();
         CloudBlockBlob blob;

         if (sample.Blob != null)
         {
            blob = blobContainer.GetBlockBlobReference(sample.Blob);
            blob.Delete();
         }

         if (sample.SampleBlob != null)
         {
            blob = blobContainer.GetBlockBlobReference(sample.SampleBlob);
            blob.Delete();
         }
      }

      // PUT: api/Data/5
      public IHttpActionResult Put(String id)
      {
         // PUT – see also ProductsController.cs from Lab 4
         // Create a retrieve operation.
         // id is a parameter of method and forms the row key
         TableOperation retrieveOperation =
         TableOperation.Retrieve<AudioSampleEntityModel>(partitionName, id);

         TableResult getOperationResult = table.Execute(retrieveOperation);
         if (getOperationResult.Result == null)
            return NotFound();

         AudioSampleEntityModel sample = (AudioSampleEntityModel)getOperationResult.Result;
         deleteOldBlobs(sample);

         try
         {
            CloudBlobContainer blobContainer = _blobStorageService.getCloudBlobContainer();

            name = string.Format("{0}{1}", Guid.NewGuid(), ".mp3");

            String path = "/mp3s" + name;

            var baseUrl = Request.RequestUri.GetLeftPart(UriPartial.Authority);
            String sampleURL = baseUrl.ToString() + "/api/data/" + id;

            sample.SampleBlobURL = sampleURL;
            sample.Blob = path;
            sample.CreatedDate = DateTime.Now;
            sample.SampleDate = null;

            var updateOperation = TableOperation.InsertOrReplace(sample);

            table.Execute(updateOperation);

            CloudBlockBlob blob = blobContainer.GetBlockBlobReference(sample.Blob);

            var request = HttpContext.Current.Request;

            blob.Properties.ContentType = "audio/mpeg3";
            blob.UploadFromStream(request.InputStream);
         }
         catch (Exception e)
         {
            System.Diagnostics.Trace.WriteLine("DataController(PUT): " + e.Message);
            return BadRequest("DataController(PUT): " + e.Message);
         }

         try
         {
            CloudQueue sampleQueue = _queueStorageService.getCloudQueue();
            var queueMessageSample = new AudioSampleEntityModel(partitionName, id);
            sampleQueue.AddMessage(new CloudQueueMessage(JsonConvert.SerializeObject(queueMessageSample)));
         }
         catch (Exception e)
         {
            System.Diagnostics.Trace.WriteLine("DataController(PUT): " + e.Message);
            return BadRequest("DataController(PUT): " + e.Message);
         }

         System.Diagnostics.Trace.WriteLine(String.Format("*** WebRole: Enqueued '{0}'", sample.Blob));
         return StatusCode(HttpStatusCode.NoContent);
      }
   }
}

This is the webjob which i think is working fine. 我认为这是webjob,效果很好。

public class Functions
{
    public static void GenerateSample(
        [QueueTrigger("audiosamplemaker")] AudioSampleEntityModel sampleInQueue,
        [Table("Samples", "{PartitionKey}", "{RowKey}")] AudioSampleEntityModel sampleInTable,
        [Blob("audiocollection/audio/{queueTrigger}")] CloudBlockBlob inputBlob,
        [Blob("audiocollection/samples/{queueTrigger}")] CloudBlockBlob outputBlob, TextWriter logger,
        [Table("Samples")] CloudTable tableBinding, TextWriter kek)
    {
        //use log.WriteLine() rather than Console.WriteLine() for trace output
        logger.WriteLine("GenerateSample() started...");
        logger.WriteLine("Input blob is: " + sampleInQueue);

        // Open streams to blobs for reading and writing as appropriate.
        // Pass references to application specific methods
        using (Stream input = inputBlob.OpenRead())
        using (Stream output = outputBlob.OpenWrite())
        {
            createSample(input, output, 20);
            outputBlob.Properties.ContentType = "audio/mp3";
            outputBlob.Metadata["Title"] = inputBlob.Metadata["Title"];
        }

        logger.WriteLine("GenerateSample() completed...");
    }

    private static void createSample(Stream input, Stream output, int duration)
    {
        using (var reader = new Mp3FileReader(input, wave => new NLayer.NAudioSupport.Mp3FrameDecompressor(wave)))
        {
            Mp3Frame frame;
            frame = reader.ReadNextFrame();
            int frameTimeLength = (int)(frame.SampleCount / (double)frame.SampleRate * 1000.0);
            int framesRequired = (int)(duration / (double)frameTimeLength * 1000.0);

            int frameNumber = 0;
            while ((frame = reader.ReadNextFrame()) != null)
            {
                frameNumber++;

                if (frameNumber <= framesRequired)
                {
                    output.Write(frame.RawData, 0, frame.RawData.Length);
                }
                else break;
            }
        }
    }
}

In your web api controller, the put method only has one parameter named 'id'. 在您的Web api控制器中,put方法只有一个名为“ id”的参数。 But in your client, you also passed a stream content in put method. 但是在客户端,您还通过put方法传递了流内容。 So you couldn't call web api method successfully. 因此,您无法成功调用Web api方法。 And for this stream content, you could set a string or model type in Put method instead of file stream. 对于此流内容,可以在Put方法中设置字符串或模型类型,而不是文件流。

According to your description, I suppose you want to pass data from client to web api, then read data from this file path in web Api and upload data to a blob. 根据您的描述,我想您想将数据从客户端传递到Web api,然后从Web Api中的此文件路径读取数据并将数据上传到Blob。 I have created a sample demo to upload a myfile.txt to a Blob. 我创建了一个示例演示,将myfile.txt上传到Blob。 Other data types are similar to this. 其他数据类型与此类似。 You could refer to. 您可以参考。

Code in Console: 控制台中的代码:

Code in AudioSampleEntityModel class: AudioSampleEntityModel类中的代码:

public class AudioSampleEntityModel : TableEntity
    {
        public AudioSampleEntityModel()
        {

        }
        public AudioSampleEntityModel(string partitionName, string id)
        {

        }
        public string id { get; set; }
        public string Blob { get; set; }
        public string SampleBlob { get; set; }
        public string SampleBlobURL { get; set; }
        public DateTime CreatedDate { get; set; }
        public string SampleDate { get; set; }
    }

Code in Function.cs: Function.cs中的代码:

public class Functions
    {
        /// <summary>
        ///  pass the content from Queue to Blob(The content is from myfile.txt)
        /// </summary>
        /// <param name="model"></param>
        /// <param name="orderBlob"></param>
        public static void MultipleOutput(
             [QueueTrigger("myqueue2")] AudioSampleEntityModel model,
             [Blob("orders/myfile")] out string orderBlob) //create a container named 'orders'
        {
            orderBlob = model.SampleBlob;    //store the content from SampleBlob property to Blob
        }
}

Code in Program: 程序中的代码:

class Program
    {
        static void Main() {
            Console.WriteLine("----------------Update Employee -------------------");
            Console.WriteLine("Enter id which you want to update");
            string id = Console.ReadLine();
            var response=DemoData(id).Result;
            Console.WriteLine("the data from webapi: "+response);
            var host = new JobHost();
           // The following code ensures that the WebJob will be running continuously
            host.RunAndBlock();
        }
        public static async Task<string> DemoData(string id)
        {
            HttpClient client = new HttpClient();        
            string path = "http://localhost:53581/api/values/" + id;
            Console.WriteLine("Enter the file name.");
            string fileName = Console.ReadLine();
            string filepath = "E:\\JanleyZhang\\" + fileName;
            var filepathJson = JsonConvert.SerializeObject(filepath);// convert other FileStream type to json string
            var data = new StringContent(content: filepathJson,
             encoding: Encoding.UTF8,
             mediaType: "application/json");
            var response = await client.PutAsync(path, data);//get response from web api
            var content = response.Content;
            var result = await content.ReadAsStringAsync();//read content from response


            //upload the data to a queue
            string connectionString = AmbientConnectionStringProvider.Instance.GetConnectionString(ConnectionStringNames.Storage);
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);

            CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
            CloudQueue queue = queueClient.GetQueueReference("myqueue2");
            queue.CreateIfNotExists();

            AudioSampleEntityModel model = new AudioSampleEntityModel()
            {
                id=id,
                SampleBlob=result //pass  the result to this property
            };
            queue.AddMessage(new CloudQueueMessage(JsonConvert.SerializeObject(model))); //store the file content to queue
            return result;
        }
}

Code in api controller: api控制器中的代码:

public string Put(string id, [FromBody]string filepath) //pass  two parameters
        {
            string b = "The id and model id are not equal.";
            if (id == "1")
            {             
                FileStream fs = File.OpenRead(filepath);               
                    byte[] byt = new byte[fs.Length];
                    UTF8Encoding temp = new UTF8Encoding(true);
                    while (fs.Read(byt, 0, byt.Length) > 0)
                    {
                       b=temp.GetString(byt);//read the content from myfile.txt
                    // The operation about uploading a blob .........
                    }
                return b;               
            }
            return b;
        }

You could see the result like this: 您可以看到如下结果: 关于Web Job的图像

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM