0

Alright. I can get the HTML I need from the page (it's all in a DIV). That's not the problem. What I need to do is take the HTML and pass it, via a C# class into a controller.

I tried doing something like this with knockout/jQuery:

    var Details = $("#Details").html();
    console.log(Details);

    DetailsPdf.DetailsMarkup = JSON.stringify(Details);

    var jsonData = ko.toJS(Details);

    ko.utils.postJson("/MyController/MyAction", DetailsPdf);

The knockout actually DOES get me the relevant HTML. But when I pass it to my class, I get an exception that reads:

A potentially dangerous Request.Form value was detected from the client.

Then it partially shows the HTML I was sending as a part of the exception. I can't even seem to pass in the entities themselves without getting that exception.

This is an app with certain company-mandated security features, so turning off validation is not an option.

I need the HTML, or at least a way to re-create it on the server in the C#.

I'm still fairly new to knockout. Does anyone have any suggestions here?

MJR
  • 169
  • 2
  • 15
  • Sounds like you're using anti forgery tokens. We need to see the relevant C# bits to be able to help. It would also help if you change your JS snippet to contain stubbed data instead of `$("#Details")`, because now we're missing part of that picture. – Jeroen Feb 15 '16 at 21:54
  • Essentially, I basically want to return an HTML table, and save it as a PDF. So I'd need to return the Table, TR, TD, and so forth. – MJR Feb 15 '16 at 22:22
  • Could be. But without the code / a repro, it's impossible for us to help you without resorting to guessing. – Jeroen Feb 16 '16 at 06:04

2 Answers2

0

You should be able to decorate your model (the one that the controller action is expecting) with the [AllowHtml] attribute on the property that has the HTML.

When you do that, MVC skips the validation for that property.

Here's a link to the documentation for more information.

Note Use this ONLY when you need to. It does open a vector for XSS if misused.


Edit: If for some reason, You can't use the [AllowHtml] attribute, you can turn off validating the request for that one action with [ValidateInput(false)].

Same rules apply. Use that very sparingly. This means none of security validations will run against that particular model in that particular action only.

Justin Self
  • 6,137
  • 3
  • 33
  • 48
  • Unfortunately, I don't seem to be able to add the AllowHtml (or, at least I can't find it on my machine). This particular app, I don't believe, is running on 4.0. They do keep a pretty tight leash on security here, I'll say that. I do have to wonder if it's possible for me to convert the string to a byte array, though there may be size limitations there. – MJR Feb 15 '16 at 22:24
  • @MJR I updated the answer to say you can also use `[ValidateInput(false)]`. However, AllowHtml has been in MVC for quite awhile (at least MVC3, probably earlier). You may be missing a reference? – Justin Self Feb 15 '16 at 22:28
  • I already tried the ValidateInput thing. The C# threw an exception before it even got to my controller. I'm probably just missing a reference somewhere for the AllowHtml. – MJR Feb 15 '16 at 22:35
  • @MJR Just to be safe, could you post the relevant parts of the controller (including any system using statements)? – Justin Self Feb 15 '16 at 22:36
0

You should have mentioned that:

This is an app with certain company-mandated security features, so turning off validation is not an option.

In your recent question Using iTextSharp with the knockout JavaScript framework?. I could have provided this answer there.

I'm not sure why decorating the controllers Action with [ValidateInput(false)] isn't working, but that answer's fully working source code is available. Whatever the reason, you should only need a few changes to workaround the issue:

(1) Base64 encode the HTML in your JavaScript:

ko.utils.postJson("/MyController/MyAction", window.btoa(DetailsPdf));

(2) Decode string in your MVC Controller:

[HttpPost]
public ActionResult Index(string xHtml)
{
    xHtml = Encoding.UTF8.GetString(Convert.FromBase64String(xHtml));

(3) Deserialize that string to your model / entities with Json.Net or other.

Above steps have also been tested and verified working. ;)

Community
  • 1
  • 1
kuujinbo
  • 9,272
  • 3
  • 44
  • 57
  • Genius, @kuujinbo. That's just what I was looking for! Your answer has been accepted. – MJR Feb 16 '16 at 15:44