发生错误.",ExceptionMessage:“提供了无效的'HttpContent'实例

编程入门 行业动态 更新时间:2024-10-28 13:16:31
本文介绍了发生错误.",ExceptionMessage:“提供了无效的'HttpContent'实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

尝试将文件添加到http REST调用中,出现此错误:

Trying to add a file to an http rest call I get this error:

responseJson = {消息:发生错误.",ExceptionMessage: 提供了无效的'HttpContent'实例. 'multipart/'. ↵参数名称:内容",异常类型: "System.ArgumentException",StackTrace:位于 System.Net.Http.Formatting.Parsers.MimeMulti…tpControllerDispatcher.d__1.MoveNext()}

responseJson = {Message: "An error has occurred.", ExceptionMessage: "Invalid 'HttpContent' instance provided. It does n…rting with 'multipart/'. ↵Parameter name: content", ExceptionType: "System.ArgumentException", StackTrace: " at System.Net.Http.Formatting.Parsers.MimeMulti…tpControllerDispatcher.d__1.MoveNext()"}

我的反应成分:

import React, { Component } from 'react'; import { Row, Col } from 'antd'; import PageHeader from '../../components/utility/pageHeader'; import Box from '../../components/utility/box'; import LayoutWrapper from '../../components/utility/layoutWrapper.js'; import ContentHolder from '../../components/utility/contentHolder'; import basicStyle from '../../settings/basicStyle'; import IntlMessages from '../../components/utility/intlMessages'; import { adalApiFetch } from '../../adalConfig'; export default class extends Component { constructor(props) { super(props); this.state = {TenantId: '', TenantUrl: '', TenantPassword: '' }; this.handleChangeTenantUrl = this.handleChangeTenantUrl.bind(this); this.handleChangeTenantPassword = this.handleChangeTenantPassword.bind(this); this.handleChangeTenantId= this.handleChangeTenantId.bind(this); this.handleSubmit = this.handleSubmit.bind(this); }; handleChangeTenantUrl(event){ this.setState({TenantUrl: event.target.value}); } handleChangeTenantPassword(event){ this.setState({TenantPassword: event.target.value}); } handleChangeTenantId(event){ this.setState({TenantId: event.target.value}); } handleSubmit(event){ event.preventDefault(); const formData = new FormData(); formData.append("TenantId", this.state.TenantId); formData.append("TenantUrl", this.state.TenantUrl); formData.append("TenantPassword", this.state.TenantPassword); const options = { method: 'put', data: formData, config: { headers: { 'Content-Type': 'multipart/form-data' } } }; adalApiFetch(fetch, "/Tenant", options) .then(response => response.json()) .then(responseJson => { if (!this.isCancelled) { this.setState({ data: responseJson }); } }) .catch(error => { console.error(error); }); } upload(e){ let data = new FormData(); //Append files to form data let files = e.target.files; for (let i = 0; i < files.length; i++) { data.append('files', files[i], files[i].name); } } render(){ const { data } = this.state; const { rowStyle, colStyle, gutter } = basicStyle; return ( <div> <LayoutWrapper> <PageHeader>{<IntlMessages id="pageTitles.TenantAdministration" />}</PageHeader> <Row style={rowStyle} gutter={gutter} justify="start"> <Col md={12} sm={12} xs={24} style={colStyle}> <Box title={<IntlMessages id="pageTitles.TenantAdministration" />} subtitle={<IntlMessages id="pageTitles.TenantAdministration" />} > <ContentHolder> <form onSubmit={this.handleSubmit}> <label> TenantId: <input type="text" value={this.state.TenantId} onChange={this.handleChangeTenantId} /> </label> <label> TenantUrl: <input type="text" value={this.state.TenantUrl} onChange={this.handleChangeTenantUrl} /> </label> <label> TenantPassword: <input type="text" value={this.state.TenantPassword} onChange={this.handleChangeTenantPassword} /> </label> <label> Certificate: <input onChange = { e => this.upload(e) } type = "file" id = "files" ref = { file => this.fileUpload } /> </label> <input type="submit" value="Submit" /> </form> </ContentHolder> </Box> </Col> </Row> </LayoutWrapper> </div> ); } }

我的租户控制器Put方法

My tenant controller Put method

[HttpPut] public async Task<IHttpActionResult> PutTenant([FromBody]Tenant tenant) { var provider = new MultipartMemoryStreamProvider(); var contentType = ""; var content = new byte[0]; await base.Request.Content.ReadAsMultipartAsync(provider); if (provider.Contents.Count > 0) { contentType = provider.Contents[0].Headers.ContentType.MediaType; content = await provider.Contents[0].ReadAsByteArrayAsync(); } CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["AzureStorageKey"].ToString()); // Create the blob client. CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); // Retrieve reference to a previously created container. CloudBlobContainer container = blobClient.GetContainerReference(ConfigurationManager.AppSettings["certificatesContainer"].ToString()); // Retrieve reference to a blob named "myblob". CloudBlockBlob blockBlob = container.GetBlockBlobReference("myblob"); // Create or overwrite the "myblob" blob with contents from a local file. blockBlob.Properties.ContentType = contentType; MemoryStream stream = new MemoryStream(content); blockBlob.UploadFromStream(stream); var tenantStore = CosmosStoreFactory.CreateForEntity<Tenant>(); tenant.content = content; tenant.CertificatePath = blockBlob.Uri; if (!ModelState.IsValid) { return BadRequest(ModelState); } var added = await tenantStore.AddAsync(tenant); return StatusCode(HttpStatusCode.NoContent); }

和租户POCO

public class Tenant { public string TenantId { get; set; } public string TenantUrl { get; set; } public Uri CertificatePath { get; set; } public string CertificatePassword { get; set; } public byte[] content { get; set; } public override string ToString() { return JsonConvert.SerializeObject(this); } }

stacktrace:

stacktrace:

" at System.Net.Http.Formatting.Parsers.MimeMultipartBodyPartParser.ValidateArguments(HttpContent content, Int64 maxMessageSize, Boolean throwOnError) at System.Net.Http.Formatting.Parsers.MimeMultipartBodyPartParser..ctor(HttpContent content, MultipartStreamProvider streamProvider, Int64 maxMessageSize, Int32 maxBodyPartHeaderSize) at System.Net.Http.HttpContentMultipartExtensions.<ReadAsMultipartAsync>d__0`1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at TenantManagementWebApi.Controllers.TenantController.<PutTenant>d__2.MoveNext() in C:\Users\levm3\source\repos\TenantManagementWebApi\Controllers\TenantController.cs:line 48 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__3`1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"

更新1:

当我远程连接调试器时,承租人参数为null,因此在客户端组件上设置参数时一定出错了.

When I attach the debugger remotely the tenant parameter is null, so something must be wrong when setting the parameters on the client component.

推荐答案

我猜您的[FromBody]Tenant tenant为空,因为您使用的是multipart/form-data.

I guess your [FromBody]Tenant tenant is null because you use multipart/form-data.

在这种情况下,默认的模型绑定器无法解析您的模型.

The default model binder can not resolve your model in this case.

请查看Microsoft 文档(读取表单控制数据).

Please review example from Microsoft documentation (section Reading Form Control Data).

您需要使用MultipartFormDataStreamProvider读取模型数据.如我所见,您仅将提供程序用于读取文件内容.而且,您还可以从FormData属性读取模型数据(例如TenantId,TenantUrl等).

You need to read your model data using MultipartFormDataStreamProvider. As I can see you use the provider only for file content reading. But also you can read your model data (like TenantId, TenantUrl, etc) from FormData property.

作为第二种(也是更通用的)方法,您可以创建自己的 IModelBinder 实现.

As second (and more general) approach you can create your own IModelBinder implementation.

在这里您可以查看我实现IModelBinder的示例(这是来自真实项目的代码):

Here you can review example of my implementation of IModelBinder (It is code from real project):

public class NativeTranslateModelBinder : IModelBinder { public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { if (bindingContext.ModelType != typeof(NativeTranslateViewModel)) { return false; } var task = Task.Run(async () => { var model = new NativeTranslateViewModel(); if (!actionContext.Request.Content.IsMimeMultipartContent()) { bindingContext.ModelState.AddModelError(bindingContext.ModelName, "WebRequeest content 'multipart/form-data' is valid"); } else { var provider = await actionContext.Request.Content.ReadAsMultipartAsync(); var fileContent = provider.Contents.FirstOrDefault(n => n.Headers.ContentDisposition.Name.Equals("file")); if (fileContent == null) { bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Section 'file' is missed"); } var modelContent = provider.Contents.FirstOrDefault(n => n.Headers.ContentDisposition.Name.Equals("model")); if (modelContent == null) { bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Section 'model' is missed"); } if (fileContent != null && modelContent != null) { model = JsonConvert.DeserializeObject<NativeTranslateViewModel>(await modelContent.ReadAsStringAsync()); model.Text = "<NativeTranslation>"; model.FileData = await fileContent.ReadAsByteArrayAsync(); model.FileName = fileContent.Headers.ContentDisposition.FileName; } } return model; }); task.Wait(); bindingContext.Model = task.Result; return true; } }

我们可以很容易地使用新型活页夹:

We can use new model binder very easy:

[HttpPost] public HttpResponseMessage UploadNativeDocument([ModelBinder(typeof(NativeTranslateModelBinder))] NativeTranslateViewModel model)

现在,我们可以在控制器动作中使用模型和模型属性.

Now we can use our model and model properties inside controller action.

更多推荐

发生错误.",ExceptionMessage:“提供了无效的'HttpContent'实例

本文发布于:2023-10-22 23:47:52,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1519097.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:发生错误   实例   quot   ExceptionMessage   HttpContent

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!