在同一个 API 调用 c# 中上传文件和数据

Upload a file and data in same API call c#

经过大量研究,我发布了这个问题,因为我自己无法弄清楚。

场景是我需要将以下参数传递给 Web API 2 controller in .Net framework 4.8 中的 HttpPost 请求:

我的前端Angular代码是:

saveNewsArticle(data) {
    return new Observable(observer => {
      let apiStr = this.apiStrBase + "SaveNewsArticle";

      let formData = new FormData();
      formData.append('date', data.publishDate);
      formData.append('author', data.author);
      formData.append('title', data.title);
      formData.append('image', data.image);
      formData.append('content', data.content);

      this.httpClient.post(apiStr, formData).subscribe((result) => {
        observer.next({ result: true, data: result });
      },
        error => {
          observer.next({ result: false });
        }
      );
    });
  }

我的 C# 代码是:

   [HttpPost]
   public void SaveNewsArticle()
   {
       var date = HttpContext.Current.Request.Params["date"];
       var author = HttpContext.Current.Request.Params["author"];
       var title = HttpContext.Current.Request.Params["title"];
       var content = HttpContext.Current.Request.Params["content"];
       var image = HttpContext.Current.Request.Files.Count > 0 ? HttpContext.Current.Request.Files[0] : null;
   }

所有这些都工作正常,但是,我正在使用 WYSIWYG 编辑器来获取文本的样式,因此 contenthtml,例如,

这是我的内容

,我在 c# 中遇到此错误:

System.Web.HttpRequestValidationException: A potentially dangerous Request.Form value was detected from the client

以下是我目前尝试过的:

  1. 我不想用<httpRuntime requestValidationMode="2.0" />

  2. 我可以通过它作为模型public void SaveArticle(Article article) 这让一切都很好,但图像总是 null.

  3. 我可以替换 '<''>' 并解决问题 对我来说,但这不是应该做的。这是一个黑客。

  4. 在 MVC 中我们可以只使用 [ValidateInput(false)][AllowHtml] 但不能在 Web API 2.

    上使用
  5. 我是否应该实现一个自定义格式化程序来处理 multipart/form-data 就像完成 here

非常感谢help/guidance。

向控制器提交 HTML 代码的替代方法是

  1. 提交为 base 64 字符串
  2. 提交为 HTML 编码字符串

我个人认为 base 64 更直接,其中

JavaScript (Encode)

formData.append('content', btoa(data.content));

C# (Decode)

var content = Encoding.UTF8.GetString(Convert.FromBase64String(HttpContext.Current.Request.Params["content"]));