c# - 如何通过文件上传发布简单的 JSON 数据?

标签 c# typescript servicestack

我正在尝试在 ServiceStack TypeScript 客户端中设置文件上传请求,其中还包括文件相关的月份。如何设置请求以便两者都到达服务器?

我尝试了各种更改,包括手动更改 header 以尝试强制 Content-Type 为 application/json,但这没有用(但我怀疑即使成功了也会中断文件上传)。

客户端API:

export const serviceApi = {
    importData: (month: string, file: File) => {
        var client = new JsonServiceClient("");
        var request = new DTOs.ImportData();

        // At this point, the month has a value
        request.month = month.replace('/', '-').trim();

        let formData = new FormData();
        formData.append('description', file.name);
        formData.append('type', 'file');
        formData.append('file', file);

        const promise = client.postBody(request, formData);
        return from(promise);
    },
};

DTO定义:

[Route("/api/data/import/{Month}", "POST")]
public class ImportData : IReturn<ImportDataResponse>
{
    public string Month { get; set; }
}

public class ImportDataResponse : IHasResponseStatus
{
    public ResponseStatus ResponseStatus { get; set; }
}

服务器端 API:

[Authenticate]
public object Post(ImportData request)
{
    if (Request.Files == null || Request.Files.Length <= 0)
    {
        throw new Exception("No import file was received by the server");
    }

    // This is always coming through as null
    if (request.Month == null)
    {
        throw new Exception("No month was received by the server");
    }

    var file = (HttpFile)Request.Files[0];
    var month = request.Month.Replace('-', '/');

    ImportData(month, file);

    return new ImportDataResponse();
}

我可以看到文件在服务器端正确通过,我可以看到一个 HTTP 请求通过查询字符串参数中设置为“07-2019”的月份,但是当我中断服务器时端API函数,请求的month属性为null。

更新,这里是 HTTP 请求/响应 header :

请求 header

POST /json/reply/ImportData?month=07-2019 HTTP/1.1
Host: localhost:40016
Connection: keep-alive
Content-Length: 7366169
Origin: http://localhost:40016
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryI8CWlbw4tP80PkpZ
Accept: */*
Referer: http://localhost:40016/data
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Cookie: _ga=GA1.1.673673009.1532913806; ASP.NET_SessionId=gtwdk3wsvdn0yulhxyblod3g; __utmc=111872281; __utmz=111872281.1533684260.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); ss-opt=perm; __utma=111872281.673673009.1532913806.1550789161.1550794391.20; _gid=GA1.1.893581387.1558389301; ss-id=kfq4G0GYb3WldSdCaRyJ; ss-pid=aZ400sqM4n3TQgNVnHS2

响应头

HTTP/1.1 500 Exception
Cache-Control: private
Content-Type: application/json; charset=utf-8
Vary: Accept
Server: Microsoft-IIS/10.0
X-Powered-By: ServiceStack/5.10 NET45 Win32NT/.NET
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RTpcVEZTXFNvdXJjZVxNZWRpc2VuXFdlYnNpdGVzXE9OaWlDU1xNYWluXFNvdXJjZVxPbmlpY3NSZWFjdC1QYXltZW50c1xPbmlpY3NSZWFjdFxPbmlpY3NSZWFjdFxqc29uXHJlcGx5XEltcG9ydE1CU0NvZGVz?=
X-Powered-By: ASP.NET
Date: Tue, 21 May 2019 21:49:03 GMT
Content-Length: 605

查询字符串参数

month=07-2019

最佳答案

您将能够使用 JavaScript's fetch API 上传文件直接,例如:

let formData = new FormData();
formData.append('description', file.name);
formData.append('type', 'file');
formData.append('file', file);

fetch('/api/data/import/07-2019', {
    method: 'POST',
    body: formData
});

否则如果你想使用ServiceStack的TypeScript JsonServiceClient您需要使用允许您使用单独的请求正文发布请求 DTO 的 API,例如:

formData.append('month', '07-2019');
client.postBody(new ImportData(), formData);

关于c# - 如何通过文件上传发布简单的 JSON 数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56245843/

相关文章:

jquery - ServiceStack 反序列化在 jQuery 请求上失败,但在 C# 客户端上失败

c# - INotifyPropertyChanged 未在 ItemsControl 内的 ViewModel 上触发

c# - 背景 worker 。如何通过在 TreeView 中导航来显示当前进程?

c# - iTextSharp 生成的 PDF : How to send the pdf to the client and add a prompt?

c# - C# 中的正则表达式 (Regex)

angular - ionic CLI 启动 : starterkit v3?

requirejs - 使用通过 requirejs.config 提供的别名导入 TypeScript 外部模块

带有--strictNullCheck的 typescript -在单独的方法中检查不为空

c# - 如何使用service.stack.redis从管道获取结果

ssl - 使用 ServiceStack.Redis 连接到 TSL Redis 云