使用 axios 从 vue 上传 XML 文件到 asp .net core
Posted
技术标签:
【中文标题】使用 axios 从 vue 上传 XML 文件到 asp .net core【英文标题】:Upload a XML file from vue with axios to asp .net core 【发布时间】:2020-08-10 07:24:11 【问题描述】:我正在努力将带有 axios 的 xml 文件上传到我的 asp .net 服务器。我正在使用来自 vue 端的以下代码来获取一个 xml 文件,该文件正在工作,然后将其上传到我的服务器:
uploadXmlFile(file: any)
const rawFile = new XMLHttpRequest();
rawFile.open('GET', file, false);
rawFile.onreadystatechange = () =>
if (rawFile.readyState === 4)
if (rawFile.status === 200 || rawFile.status === 0)
const allText = rawFile.responseText;
axios.post(`$url`, rawFile,
headers:
'Content-Type': 'application/xml',
'Accept-Language': 'application/xml',
,
);
;
rawFile.send(null);
在 asp .net 端我得到了这个功能:
[HttpPost]
public IActionResult Post(object xml)
// Do something with the xml
...
上传文件会导致代码 415:不支持的媒体类型。
我发现了一些将 xml 格式化程序添加到我的项目的建议,但没有用,而且我不想解析 xml 文件,我只想将文件保存到我的文件系统。
我尝试结合不同的媒体类型上传 rawFile 和解析的文本,例如text/plain、text/xml 和 application/xml
我也尝试添加接受语言
我还使用此函数头尝试了 microsoft 文档中建议的方法:
public async Task<IActionResult> OnPostUploadAsync(List<IFormFile> files)
我尝试使用 Postman 进行调试,上传了一张简单的图片,但出现了同样的错误。
【问题讨论】:
不要不发送同步的XMLHttpRequests! @AluanHaddad 是的,我知道,但这不应该是这里的问题,对吧?我的意思是我在上传之前获得了 xml 文件。一旦这些东西起作用了,我会改进它...... @TobiasW 您能否尝试再次执行脚本,但这次从浏览器的开发人员工具和网络选项卡上传屏幕截图。我主要想看看请求标头和正文。我认为请求或操作的参数类型(object
)有错误。
@vchan 我不太确定如何使用浏览器开发工具上传图片。但是我也在用 Postman 进行调试,并尝试用 Postman 上传图像,这也不起作用并给了我同样的错误
@vchan 一旦我将我的正文更改为 json 对象,它就可以工作,但所有其他内容类型都被阻止
【参考方案1】:
如果你这样写后端,它总是会尝试将内容序列化为 JSON,因为默认的序列化器。如果您发送内容类型 XML,它将不知道如何将您的 XML 反序列化为对象。
这是我们通常处理文件上传的方式:
[HttpPost]
public async Task<IActionResult> ReceiveFileUpload(CancellationToken cancellationToken = default(CancellationToken))
var contentType = Request.ContentType; // Or HttpContext.Request
var stream = Request.Body; // Or HttpContext.Request
// Process file stream in whatever way, e.g. XmlDocument.Load(stream);
这至少应该使它在例如邮递员。
您的 axios 客户端看起来几乎没问题,有几点需要注意:
您可能想发帖alltext
,而不是rawFile
你应该删除'Accept-Language': 'application/xml'
我们通常使用 FileReader 来获取文件,不太确定您在做什么以及是否正确。
axios.post(url, content,
headers:
"Content-Type": "application/xml"
)
<input type='file' accept='text/plain' onchange='openFile(event)'>
var openFile = function(event)
var input = event.target;
var text = "";
var reader = new FileReader();
var onload = function(event)
text = reader.result;
console.log(text);
;
reader.onload = onload;
reader.readAsText(input.files[0]);
;
(https://codepen.io/mlasater9/pen/jqQdOM/)
【讨论】:
您建议的服务器代码更改有效。但是缺少Request对象的声明,不是吗?Request
应该始终在您的 ASP.NET 控制器中可用。您可以将流解析为您喜欢的任何结构,例如XmlDocument
。你还需要别的吗?
你说的是 ASP.NET 还是 ASP.NET CORE,这个问题是关于哪个?
ASP.NET 核心。你也可以试试HttpContext.Request
而不是Request
我不太明白你的问题是什么,也许可以为它打开一个新问题?【参考方案2】:
首先,关于您的Front-end
,您需要发送allText
常量而不是rawFile
。所以你的代码会是这样的:
axios.post(
url,
allText,
headers:
'Content-Type': 'application/xml'
)
现在对于您的Back-end
,默认情况下ASP.NET core
无法识别xml
。您需要转到位于应用程序根目录的文件 Startup.cs 和方法 ConfigureServices
,您需要添加 services.AddXmlSerializerFormatters()
。所以你的代码会是这样的:
services
.AddMvc()
.AddXmlSerializerFormatters()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1); // this depends on your .net core version
您还必须为要解析的xml
创建一个类模型。例如,如果您有这样的xml
<document>
<id>12345</id>
<content>This is a Test</content>
<author>vchan</author>
</document>
你应该有一个像下面这样的类模型
[XmlRoot(ElementName = "document", Namespace = "")]
public class DocumentDto
[XmlElement(DataType = "string", ElementName = "id")]
public string Id get; set;
[XmlElement(DataType = "string", ElementName = "content")]
public string Content get; set;
[XmlElement(DataType = "string", ElementName = "author")]
public string Author get; set;
另外,.net
可以自己理解原始的 xml
正文,因此,您的控制器的操作应该如下所示
[HttpPost]
public IActionResult TestMethod([FromBody] DocumentDto xml)
// Do something with the xml
请注意,您应该始终使用HTTP header
Content-Type: application/xml
来处理您的请求,以便.net
能够理解、解析和反序列化它。您无需为要实施的每个不同操作重新发明***,.net
为您完成!
【讨论】:
以上是关于使用 axios 从 vue 上传 XML 文件到 asp .net core的主要内容,如果未能解决你的问题,请参考以下文章
从 Axios 响应中解析 XML,推送到 Vue 数据数组