我编写了一些代码 (MetadataProcessor) 来定位 xml 文件并将其发送到 API ( http://localhost:5000/api/Events/UploadAzureEncodedMetadata ) 以进行解析。但是,调用 API 时,IFormFile 参数始终为空。我已经用 fiddler 检查了生成的 http 请求,以确定是什么导致了模型绑定问题(如果是这样的话),但我没有发现任何问题。
元数据处理器:
// Build a path to the directory containing the metadata file
string folderName = string.Format("OUTPUT_ENCODER_{0}_{1}", eventId, id);
string folderPath = Path.Combine(
this._config.MediaBasePath,
clientId.ToString(),
eventId.ToString(),
"results",
folderName);
// Find the metadata file
string fileName = null;
byte[] data = null;
bool exists = false;
string[] files = Directory.GetFiles(folderPath);
foreach (var file in files)
{
if (file.EndsWith("_metadata.xml"))
{
data = File.ReadAllBytes(file);
exists = true;
fileName = file;
break;
}
}
// Generate token for access to Events controller
TokenProvider tokens = new TokenProvider(this._config, this._logger);
var authValue = new AuthenticationHeaderValue("Bearer", tokens.GetTokenObject(clientId));
// Build the HttpClient
HttpClient client = new HttpClient()
{
DefaultRequestHeaders =
{
Authorization = authValue
}
};
// Bundle the xml data into the request body
ByteArrayContent formFile = new ByteArrayContent(data, 0, data.Length);
MultipartFormDataContent multiContent = new MultipartFormDataContent();
multiContent.Add(formFile, "formFile", fileName);
// Post to EventsController
var baseUri = new Uri(this._config.BaseUrl);
var url = new Uri(baseUri, string.Format("{0}api/Events/UploadAzureEncodedMetadata/{1}", baseUri, videoId));
var result = await client.PostAsync(url.ToString(), multiContent);
API 中的 MVC 控制器:
[HttpPost("UploadAzureEncodedMetadata/{id}")]
[ProducesResponseType(201)]
[ProducesResponseType(400)]
[ProducesResponseType(401)]
[ProducesResponseType(404)]
public async Task<IActionResult> UpdateDuration([FromRoute]Guid id, [FromForm]IFormFile formFile)
{
// Find the video to update
var video = await this.context.Videos.Where(v => v.Id == id).SingleOrDefaultAsync();
if(formFile == null)
{
return this.BadRequest();
}
// Ensure that the service account has authorization
var eventId = video.EventId;
if (!await this.securityProvider.HasEventEditAccessAsync(eventId))
{
return this.Unauthorized();
}
// Attempt to deserialize the xml
int videoDuration = 0;
try
{
var serializer = new XmlSerializer(typeof(AssetFiles));
Stream stream = formFile.OpenReadStream();
var assetFiles = (AssetFiles)serializer.Deserialize(stream);
// Find duration and convert to seconds
string durationString = assetFiles.AssetFile.Duration;
TimeSpan durationTimeSpan = XmlConvert.ToTimeSpan(durationString);
videoDuration = (int)durationTimeSpan.TotalSeconds;
}
catch(Exception ex)
{
return this.BadRequest();
}
// Update the video entry
video.Duration = videoDuration;
await this.context.SaveChangesAsync();
return this.NoContent();
}
最后,这是 MetadataProcessor 产生的 http 请求的原始读数,导致控制器中 formFile 的值为空:
POST http://localhost:5000/api/Events/UploadAzureEncodedMetadata/dc14829c-3d1b-4379-615b-08d5f8d07e16 HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1OWNiODg5YS01YjRjLTRlMzUtOWMyOS0zYWQ3MGU4NTJhYTgiLCJqdGkiOiI5OTU3MWIyMy0xYTQwLTQ0OTUtOTE2Zi03NDY5YjYwYzI1N2MiLCJpYXQiOjE1MzM4MzM4NzAsIkV2ZW50UmVnVXNlciI6ZmFsc2UspOgHjFVudElkIjoiMTdhMjc4NDYtOTc1My00OGEzLTRlYzEtMDhkNGUxMjgwZjVhIiwibmJmIjoxNTMzODMzODcwLCJleHAiOjE1MzM4MzM5MzAsImlzcyI6IjYzYmVmM2NkYTM1OTRmZjBhOTdiYWFiYWJjYTQzODhmIiwiYXVkIjoiSW5mZXJub0NvcmUifQ.rhIjYRUtFjHWrrgd9XnmW4kMXaZ5UFyr2ApNK1EBJRI
Content-Type: multipart/form-data; boundary="1b6c2d6e-53d6-414c-bb1b-681ff9c766f0"
Content-Length: 2951
Host: localhost:5000
--1b6c2d6e-53d6-414c-bb1b-681ff9c766f0
Content-Disposition: form-data; name=formFile; filename="C:\tmp\17a27846-9753-48a3-4ec1-08d4e1280f5a\213e65ee-fff9-4668-b123-7d0746bb4b05\results\OUTPUT_ENCODER_213e65ee-fff9-4668-b123-7d0746bb4b05_00000000-0000-0000-0000-000000000000\a35f0612-7a07-4bec-a9fd-a61d2a2f71bb_metadata.xml"; filename*=utf-8''C%3A%5Ctmp%5C17a27846-9753-48a3-4ec1-08d4e1280f5a%5C213e65ee-fff9-4668-b123-7d0746bb4b05%5Cresults%5COUTPUT_ENCODER_213e65ee-fff9-4668-b123-7d0746bb4b05_00000000-0000-0000-0000-000000000000%5Ca35f0612-7a07-4bec-a9fd-a61d2a2f71bb_metadata.xml
<?xml version="1.0" encoding="utf-8"?>
<AssetFiles xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/windowsazure/mediaservices/2014/07/mediaencoder/inputmetadata">
<AssetFile Name="bcff8e9a-7cb7-4d09-abd2-f04a83df1be1.mp4" Size="383631" Duration="PT5.568S" NumberOfStreams="2" FormatNames="mov,mp4,m4a,3gp,3g2,mj2" FormatVerboseName="QuickTime / MOV" StartTime="PT0S" OverallBitRate="551">
<VideoTracks>
<VideoTrack Id="1" Codec="h264" CodecLongName="H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10" TimeBase="1/90000" NumberOfFrames="166" StartTime="PT0S" Duration="PT5.533S" FourCC="avc1" Profile="Constrained Baseline" Level="3.0" PixelFormat="yuv420p" Width="560" Height="320" DisplayAspectRatioNumerator="0" DisplayAspectRatioDenominator="1" SampleAspectRatioNumerator="0" SampleAspectRatioDenominator="1" FrameRate="30" Bitrate="465" HasBFrames="0">
<Disposition Default="1" Dub="0" Original="0" Comment="0" Lyrics="0" Karaoke="0" Forced="0" HearingImpaired="0" VisualImpaired="0" CleanEffects="0" AttachedPic="0" />
<Metadata key="creation_time" value="2010-03-20T21:29:11.000000Z" />
<Metadata key="language" value="und" />
<Metadata key="encoder" value="JVT/AVC Coding" />
</VideoTrack>
</VideoTracks>
<AudioTracks>
<AudioTrack Id="2" Codec="aac" CodecLongName="AAC (Advanced Audio Coding)" TimeBase="1/48000" NumberOfFrames="261" StartTime="PT0S" Duration="PT5.568S" SampleFormat="fltp" ChannelLayout="mono" Channels="1" SamplingRate="48000" Bitrate="83" BitsPerSample="0">
<Disposition Default="1" Dub="0" Original="0" Comment="0" Lyrics="0" Karaoke="0" Forced="0" HearingImpaired="0" VisualImpaired="0" CleanEffects="0" AttachedPic="0" />
<Metadata key="creation_time" value="2010-03-20T21:29:11.000000Z" />
<Metadata key="language" value="eng" />
</AudioTrack>
</AudioTracks>
<Metadata key="major_brand" value="mp42" />
<Metadata key="minor_version" value="0" />
<Metadata key="compatible_brands" value="mp42isomavc1" />
<Metadata key="creation_time" value="2010-03-20T21:29:11.000000Z" />
<Metadata key="encoder" value="HandBrake 0.9.4 2009112300" />
</AssetFile>
</AssetFiles>
--1b6c2d6e-53d6-414c-bb1b-681ff9c766f0--
我知道还有其他方法可以上传 xml 数据,但如果可能的话,我更愿意将 xml 解析保留在 api 方面。谢谢!