我在这个问题上拔头发,我想知道是否有人可以提供帮助。
我试图创建一个POST和PUT http web api方法来处理JSON数据和图像数据。当使用Azure模拟器在我的本地计算机上运行时,这一切都很完美,但是一旦我发布到服务器,我就会收到一个AccessViolationException错误:
附加信息:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。
我使用以下代码,在对Azure进行调试时,代码在读取多部分数据时失败。
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;
}
}
正如我所说,这个代码在本地计算机上运行时效果很好,但在Azure上运行时则不行。
有什么想法吗?
由于
尼尔
答案 0 :(得分:0)
我知道这是一篇较旧的文章,但我也有同样的例外,我希望对我有用的东西可以帮助其他人。就我而言,问题在于System.Net.Http的版本不匹配。这些是我为修复而采取的步骤。
<dependentAssembly> <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-{version}" newVersion="{version}" /> </dependentAssembly>
希望这会有所帮助!