You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过现有CreateRecord方法上传ServiceNow附件(Rest API)

ServiceNow附件上传实现方案(基于不可修改的CreateRecord方法)

要通过固定参数的CreateRecord通用方法完成ServiceNow附件上传,核心是让通用方法适配ServiceNowapi/now/attachment/file接口要求的multipart/form-data请求格式,具体实现步骤如下:

1. 确保ServiceNowAttachment类包含必填字段

你的ServiceNowAttachment实体类必须包含ServiceNow接口要求的两个核心参数,同时保留文件相关属性:

public class ServiceNowAttachment
{
    // 目标表名(例如 incident、change_request)
    public string table_name { get; set; }
    // 要附加附件的记录Sys ID
    public string table_sys_id { get; set; }
    // 文件名
    public string FileName { get; set; }
    // 文件二进制数据
    public byte[] FileData { get; set; }
    // 其他可选字段(如描述等)
}

2. 调整UploadAttachment方法的参数传递逻辑

无需手动构造MultipartFormDataContent,而是通过标记请求类型的方式,让CreateRecord内部自动处理文件上传逻辑:

private async Task UploadAttachment(CRMContext crmContext, ServiceNowAttachment attachment, ServiceNowQueryOptions requestOptions)
{
    // 校验必填参数
    if (string.IsNullOrEmpty(attachment.table_name) || string.IsNullOrEmpty(attachment.table_sys_id))
        throw new ArgumentException("table_name和table_sys_id为附件上传必填字段");

    if (attachment.FileData == null || attachment.FileData.Length == 0)
        throw new ArgumentException("待上传文件数据不能为空");

    // 在请求选项中标记这是附件上传请求,用于CreateRecord内部识别
    requestOptions.Headers.Add("X-Upload-Type", "Attachment");

    // 直接调用CreateRecord,无需额外构造内容
    await this.serviceNowClient.CreateRecord<ServiceNowAttachment>(
        crmContext,
        attachment,
        null, // 附件上传无需额外字段
        requestOptions).ConfigureAwait(false);
}

3. 修改CreateRecord内部逻辑(核心适配)

虽然CreateRecord的对外参数不能修改,但内部需要增加附件上传的分支处理,自动构建符合要求的多部分请求:

public async Task<T> CreateRecord<T>(CRMContext context, T entity, JObject additionalFields, ServiceNowQueryOptions options)
{
    // 附件上传使用专属端点,其他实体使用常规表端点
    string endpoint = typeof(T) == typeof(ServiceNowAttachment) 
        ? "/api/now/attachment/file" 
        : "/api/now/table/" + GetTableName<T>();

    HttpContent content;

    // 判断是否为附件上传请求,构建multipart/form-data内容
    if (entity is ServiceNowAttachment attachment && attachment.FileData != null)
    {
        var multipartContent = new MultipartFormDataContent();
        
        // 先添加table_name和table_sys_id(必须在file参数之前)
        multipartContent.Add(new StringContent(attachment.table_name), "table_name");
        multipartContent.Add(new StringContent(attachment.table_sys_id), "table_sys_id");
        
        // 最后添加文件参数(ServiceNow要求必须放在最后)
        using var fileContent = new ByteArrayContent(attachment.FileData);
        // 可根据实际文件类型替换MIME,比如image/png、application/pdf
        fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
        multipartContent.Add(fileContent, "file", attachment.FileName);

        content = multipartContent;
    }
    else
    {
        // 原有JSON请求逻辑保持不变
        var jsonContent = new StringContent(JsonConvert.SerializeObject(entity), Encoding.UTF8, "application/json");
        // 处理additionalFields的原有逻辑...
        content = jsonContent;
    }

    // 发送请求并处理响应
    var response = await _httpClient.PostAsync(endpoint, content, options.CancellationToken);
    response.EnsureSuccessStatusCode();
    var responseContent = await response.Content.ReadAsStringAsync();
    return JsonConvert.DeserializeObject<T>(responseContent);
}

关键注意事项

  • 参数顺序严格遵守:ServiceNow的api/now/attachment/file接口要求file参数必须是请求的最后一个参数,不能调整顺序。
  • MIME类型优化:如果明确知道文件的具体类型,替换application/octet-stream为对应类型(如image/jpeg)可以提升接口兼容性。
  • 自动处理请求头:MultipartFormDataContent会自动生成正确的Content-Type头(包含边界信息),无需手动设置。

内容的提问来源于stack exchange,提问作者nikom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 15:54:59