使用带有.net框架的c#和microsoft azure,我正在尝试上传一个应该由webjob拾取的cli中的文件。我确定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));
}
根据我的理解PutAsync应该用于流式传输文件,但它给我一个错误说该命令不存在
这个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);
}
}
}
这是我觉得工作正常的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;
}
}
}
}
在您的web api控制器中,put方法只有一个名为'id'的参数。但是在您的客户端中,您还在put方法中传递了流内容。所以你无法成功调用web api方法。对于此流内容,您可以在Put方法而不是文件流中设置字符串或模型类型。
根据你的描述,我想你想要将数据从客户端传递到web api,然后从web Api中的这个文件路径读取数据并将数据上传到blob。我创建了一个示例演示,将myfile.txt上传到Blob。其他数据类型与此类似。你可以参考。
控制台代码:
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; }
}
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
}
}
程序代码:
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;
}
}
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;
}