0

My ASP.NET MVC app is hosted within an IFrame. Because of long server response time I display a waiting symbol upon the post. Meaning my post is based upon jQuery and json to and from my controller. Running my ASP.NET MVC app works fine stand alone, but not at all within an Iframe.

The IFrame is in a custom visual within PowerBI.

In Global.asax, I have this code:

AntiForgeryConfig.SuppressXFrameOptionsHeader = true;

In my controller, I have removed:

[ValidateAntiForgeryToken]

In my view, I have removed:

@Html.AntiForgeryToken()

Upon post, I get these response errors

OPTIONS https://myurl/Edit/707057500079987300 401 (Unauthorized)

Response to a preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 401.

I've changed my controller and view to use a GET request. But the same result, http error 401.

My goal is not for Site A to interact with Site B, it's just to show it.

Site B, my ASP.NET MVC app, shall do some server-side stuff and show the result.

By setting the AntiForgeryConfig.SuppressXFrameOptionsHeader = true and removed the validation I thought my goals where doable.

The request:

OPTIONS /AENettMicrofunctions/InstantReading/GetDetails/707057500079332843 HTTP/1.1
Host: aensmartgrid.ae.no
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
Access-Control-Request-Headers: x-requested-with
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: nb-NO,nb;q=0.9,no;q=0.8,nn;q=0.7,en-US;q=0.6,en;q=0.5

The response

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/8.5
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
Persistent-Auth: true
X-Powered-By: ASP.NET
Date: Thu, 21 Jun 2018 13:59:02 GMT
ntCoent-Length: 5015
Content-Encoding: gzip
Content-Length:       1651

As suggested below I have added the following to web.config

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <httpProtocol> 
        <customHeaders> 
            <add name="Access-Control-Allow-Origin" value="*" /> 
            <add name="Access-Control-Allow-Headers" value="Content-Type" />
            <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
        </customHeaders> 
    </httpProtocol>
</system.webServer>

What am I doing wrong here?

Why is the http verb OPTION, when in the jQuery it's clearly a GET? What am I missing?

The code for my view is below.

Regards Frode

@model AE.Net.MicrofunctionViews.Models.InstantReadingRequest

@{
ViewBag.Title = "Momentanavlesning spenning";
}

<div>
@Html.ValidationSummary(false, "", new { @class = "text-danger" })
<div class="form-group">
    @Html.Label("model.UsagePoint", "Målepunkt: ")
    @Html.DisplayFor(model => model.UsagePoint)
    @Html.HiddenFor(model => model.UsagePoint, "UsagePointId")
</div>
<div id="divProcessing" class="col-md-10">
    <img src="~/Content/ajax-loader.gif" />
</div>
<div id="divData" class="form-group">
    @Html.Label("model.ReadingResult", "Resultat: ")
    <img src="~/Content/GreenSmiley.jpg" id="GreenSmiley" />
    <img src="~/Content/RedSmiley.jpg"  id="RedSmiley" />
    <div>
        @Html.TextAreaFor(model => model.ReadingResult, new { @cols = "50", @rows = "4" })
    </div>
</div>
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")

<script type="text/javascript">

    $(document).ready(function () {

        // Hide the "busy" Gif at load:
        $("#divProcessing").show();
        $("#divData").hide();
        $("#GreenSmiley").hide();
        $("#RedSmiley").hide();

        var usagePointId = $("#UsagePoint").val();
        var url = "@Url.Action("GetDetails", "InstantReading")/" + usagePointId;
        $.ajax({
            url: url,
            type: "GET",
            dataType: "json",
            success: function (resp) {                    
                // Hide the "busy" gif:
                $("#divProcessing").hide();
                $("#divData").show();
                if (resp.errors) {
                    
                    var $summaryUl = $(".validation-summary-valid").find("ul");
                    $summaryUl.empty();
                    $.each(resp.errors,
                        function (a, b) {
                            $summaryUl.append($("<li>").text(b.Errors[0].ErrorMessage));
                        });
                }
                else {
                    $("#ReadingResult").val(resp.ReadingResult);
                    var ResultHaveVoltageReading = resp.ResultHaveVoltageReading;
                    if (ResultHaveVoltageReading) {
                        var ResultVoltageReadingIsOk = resp.ResultVoltageReadingIsOk;
                        if (ResultVoltageReadingIsOk) {
                            $("#GreenSmiley").show();

                        }
                        else {
                            $("#RedSmiley").show();
                        }
                    }
                }
            },
            error: function (xhr) {
                $("#divProcessing").hide();
                $("#divData").show();
                $("#ReadingResult").val(xhr.val);
            }
        })
    });
</script>
}
1
  • I don't think you need to remove ValidateAntiForgeryToken and other stuff. Have you tried adding the following code in your web.config? <configuration> <system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="SiteADomain" /> </customHeaders> </httpProtocol> </system.webServer> </configuration> Commented Jun 21, 2018 at 17:46

1 Answer 1

0

This where a CORS problem.

The OPTION request did not have any authentication in the request. Causing IIS to disregard it. A Custom http handler for the OPTION request fixed the problem.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.