0

After a lot of research, I am posting this question as I couldn't figure it out myself.

The scenario is that I need to pass the following parameters to a HttpPost request in a Web API 2 controller in .Net framework 4.8:

  • Date -> Date object
  • Author -> string
  • Title -> string
  • Content -> string
  • Image -> File object

My front end Angular code is:

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 });
        }
      );
    });
  }

My C# code is:

   [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;
   }

All of this just works fine, but, I'm using a WYSIWYG editor to get the styling of the text and hence the content is html, for example, <p>this is my content</p> and I get this error in c#:

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

enter image description here

Following is what I have tried so far:

  1. I don't want to use <httpRuntime requestValidationMode="2.0" />

  2. I can pass it as a model public void SaveArticle(Article article) which gets everything just fine but the image is always null.

  3. I can replace the '<' and '>' and that solves the problem for me but that is not how this should be done. It's a hack.

  4. In MVC we could just use [ValidateInput(false)] or [AllowHtml] but can't use it on Web API 2.

  5. Should I implement a custom formatter to handle the multipart/form-data like done here

Any help/guidance is greatly appreciated.

CodeWarrior
  • 5,026
  • 6
  • 30
  • 46
  • Can you share the code of `Article` class? How are you trying to access the `image` if you use `article` as Post Body in Action method? – Chetan Dec 07 '20 at 02:59
  • Does this answer your question? [upload file on server webfolder and post json data at the same using asp.net web api](https://stackoverflow.com/questions/64479129/upload-file-on-server-webfolder-and-post-json-data-at-the-same-using-asp-net-web) – Chetan Dec 07 '20 at 03:00
  • It's the same as the parameters that I have described in the scenario at the begining – CodeWarrior Dec 07 '20 at 03:00
  • @ChetanRanpariya The answer you suggested uses `IFormFile` which is part of `.NetCore` and I'm using `.Net framework`. Please do not vote to close this answer. If it was that easy I wouldn't have posted the question in the first place. – CodeWarrior Dec 07 '20 at 03:09
  • @CodeWarrior Is that the only exception message you're getting? The one line about dangerous form data? Or is it telling you that there is no suitable `MediaTypeFormatter` available? Are you able to upload JUST the image? If not, then there's a config or formatter issue in regards to `multipart/form-data` type requests. – jdewerth Dec 07 '20 at 03:19
  • That's the only exception I am getting, uploaded image. – CodeWarrior Dec 07 '20 at 03:27
  • Why not convert the html to base 64 string before submitting and decode it in the controller? – mylee Dec 07 '20 at 04:45
  • Have you tried to HTML encode the form value before sending it? This is a normal security feature, most of the time you'd just opt out of validating the input like you said. Since that isn't possible in this case, try encoding the input first. It should be pretty easy with Angular. – jdewerth Dec 07 '20 at 07:10
  • @mylee your suggestion solves my problem, if you would post it as an answer I'd be more than happy to accept it. – CodeWarrior Dec 08 '20 at 01:05
  • Okay sure I will do that – mylee Dec 08 '20 at 03:31

1 Answers1

1

Alternative ways to submit HTML codes to the controller is

  1. submit as base 64 string
  2. submit as HTML encoded string

Personally I think base 64 is more straightforward, where in

JavaScript (Encode)

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

C# (Decode)

var content = Encoding.UTF8.GetString(Convert.FromBase64String(HttpContext.Current.Request.Params["content"]));
mylee
  • 1,293
  • 1
  • 9
  • 14