C# System.AccessViolationException';在Azure上的System.Net.Http.Formatting.dll中发生
我正为这个问题发火,不知是否有人能帮忙 我试图创建一个POST和PUT http web api方法来处理JSON数据和图像数据。当使用Azure emulator在我的本地计算机上运行时,这一切都能很好地工作,但当我发布到服务器时,我会收到一个AccessViolationException错误,错误是: 其他信息:尝试读取或写入受保护内存。这通常表示其他内存已损坏 我正在使用下面的代码,在Azure上调试时,读取多部分数据时代码失败C# System.AccessViolationException';在Azure上的System.Net.Http.Formatting.dll中发生,c#,azure,C#,Azure,我正为这个问题发火,不知是否有人能帮忙 我试图创建一个POST和PUT http web api方法来处理JSON数据和图像数据。当使用Azure emulator在我的本地计算机上运行时,这一切都能很好地工作,但当我发布到服务器时,我会收到一个AccessViolationException错误,错误是: 其他信息:尝试读取或写入受保护内存。这通常表示其他内存已损坏 我正在使用下面的代码,在Azure上调试时,读取多部分数据时代码失败 public async Task<bool>
public async Task<bool> BindModelTask(HttpActionContext actionContext, System.Web.Http.ModelBinding.ModelBindingContext bindingContext) {
try {
if (actionContext.Request.Content.IsMimeMultipartContent()) {
var provider = await actionContext.Request.Content.ReadAsMultipartAsync<InMemoryMultipartFormDataStreamProvider>(new InMemoryMultipartFormDataStreamProvider());
FormCollection formData = provider.FormData;
FileData[] fileData = provider.GetFiles().Result;
if (formData != null && formData.Count == 1) {
Pet pet = (Pet)Newtonsoft.Json.JsonConvert.DeserializeObject(formData[0], typeof(Pet));
if (pet != null) {
petModel petModel = new petModel(pet);
if (fileData != null) {
petModel.file = fileData.FirstOrDefault();
}
bindingContext.Model = petModel;
}
}
return true;
}
}
catch (Exception ex) { throw ex; }
}
}
public class InMemoryMultipartFormDataStreamProvider : MultipartStreamProvider {
private FormCollection _formData = new FormCollection();
private List<HttpContent> _fileContents = new List<HttpContent>();
// Set of indexes of which HttpContents we designate as form data
private Collection<bool> _isFormData = new Collection<bool>();
/// <summary>
/// Gets a <see cref="NameValueCollection"/> of form data passed as part of the multipart form data.
/// </summary>
public FormCollection FormData {
get { return _formData; }
}
/// <summary>
/// Gets list of <see cref="HttpContent"/>s which contain uploaded files as in-memory representation.
/// </summary>
public List<HttpContent> Files {
get { return _fileContents; }
}
/// <summary>
/// Convert list of HttpContent items to FileData class task
/// </summary>
/// <returns></returns>
public async Task<FileData[]> GetFiles() {
return await Task.WhenAll(Files.Select(f => FileData.ReadFile(f)));
}
public override Stream GetStream(HttpContent parent, HttpContentHeaders headers) {
// For form data, Content-Disposition header is a requirement
ContentDispositionHeaderValue contentDisposition = headers.ContentDisposition;
if (contentDisposition != null) {
// We will post process this as form data
_isFormData.Add(String.IsNullOrEmpty(contentDisposition.FileName));
return new MemoryStream();
}
// If no Content-Disposition header was present.
throw new InvalidOperationException(string.Format("Did not find required '{0}' header field in MIME multipart body part..", "Content-Disposition"));
}
/// <summary>
/// Read the non-file contents as form data.
/// </summary>
/// <returns></returns>
public override async Task ExecutePostProcessingAsync() {
// Find instances of non-file HttpContents and read them asynchronously
// to get the string content and then add that as form data
CloudBlobContainer _container = StorageHelper.GetStorageContainer(StorageHelper.StorageContainer.Temp);
for (int index = 0; index < Contents.Count; index++) {
if (_isFormData[index]) {
HttpContent formContent = Contents[index];
// Extract name from Content-Disposition header. We know from earlier that the header is present.
ContentDispositionHeaderValue contentDisposition = formContent.Headers.ContentDisposition;
string formFieldName = UnquoteToken(contentDisposition.Name) ?? String.Empty;
// Read the contents as string data and add to form data
string formFieldValue = await formContent.ReadAsStringAsync();
FormData.Add(formFieldName, formFieldValue);
}
else {
_fileContents.Add(Contents[index]);
}
}
}
/// <summary>
/// Remove bounding quotes on a token if present
/// </summary>
/// <param name="token">Token to unquote.</param>
/// <returns>Unquoted token.</returns>
private static string UnquoteToken(string token) {
if (String.IsNullOrWhiteSpace(token)) {
return token;
}
if (token.StartsWith("\"", StringComparison.Ordinal) && token.EndsWith("\"", StringComparison.Ordinal) && token.Length > 1) {
return token.Substring(1, token.Length - 2);
}
return token;
}
}
公共异步任务BindModelTask(HttpActionContext actionContext,System.Web.Http.ModelBinding.ModelBindingContext bindingContext){
试一试{
if(actionContext.Request.Content.IsMimeMultipartContent()){
var provider=await actionContext.Request.Content.ReadAsMultipartAsync(新的InMemoryMultipartFormDataStreamProvider());
FormCollection formData=provider.formData;
FileData[]FileData=provider.GetFiles().Result;
if(formData!=null&&formData.Count==1){
Pet Pet=(Pet)Newtonsoft.Json.JsonConvert.DeserializeObject(formData[0],typeof(Pet));
if(pet!=null){
petModel petModel=新petModel(pet);
if(fileData!=null){
petModel.file=fileData.FirstOrDefault();
}
bindingContext.Model=petModel;
}
}
返回true;
}
}
catch(异常ex){throw ex;}
}
}
MemoryMultipartFormDataStreamProvider中的公共类:MultipartStreamProvider{
private FormCollection_formData=new FormCollection();
私有列表_fileContents=新列表();
//HttpContents指定为表单数据的索引集
私有集合_isFormData=新集合();
///
///获取作为多部分表单数据的一部分传递的表单数据。
///
公共表格收集表格数据{
获取{return\u formData;}
}
///
///获取以内存表示形式包含上载文件的列表。
///
公共列表文件{
获取{return\u fileContents;}
}
///
///将HttpContent项列表转换为FileData类任务
///
///
公共异步任务GetFiles(){
return wait Task.WhenAll(Files.Select(f=>FileData.ReadFile(f));
}
公共重写流GetStream(HttpContent父级、HttpContentHeaders头){
//对于表单数据,需要内容处置标头
ContentDispositionHeaderValue contentDisposition=headers.contentDisposition;
if(contentDisposition!=null){
//我们将把它作为表单数据进行后期处理
_Add(String.IsNullOrEmpty(contentDisposition.FileName));
返回新的MemoryStream();
}
//如果不存在内容处置标头。
抛出新的InvalidOperationException(string.Format(“在MIME多部分正文部分中未找到必需的“{0}”头字段…,“内容处置”);
}
///
///将非文件内容作为表单数据读取。
///
///
公共覆盖异步任务ExecutePostProcessingAsync(){
//查找非文件HttpContents的实例并异步读取它们
//获取字符串内容,然后将其作为表单数据添加
CloudBlobContainer\u container=StorageHelper.GetStorageContainer(StorageHelper.StorageContainer.Temp);
for(int index=0;index1){
返回token.Substring(1,token.Length-2);
}
返回令牌;
}
}
正如我所说,这段代码在本地机器上运行时效果很好,但在Azure上运行时效果不佳
有什么想法吗
谢谢
尼尔我知道这是一篇老文章,但我也有同样的例外,我希望对我有用的东西可能会帮助其他人。在我的例子中,问题在于System.Net.Http的版本不匹配。这些是我为修复而采取的步骤
希望这有帮助 还是在这里有解决办法吗?
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-{version}" newVersion="{version}" />
</dependentAssembly>