Error fetching data from ASP.NET in ReactJS

daowdos 296 Reputation points
2021-08-03T13:57:06.677+00:00

I'm using ReactJS with functional components for my front-end trying to fetch data from the ASP.NET WebService,

from File.jsx

const URL = 'http://localhost:63579/WebService.asmx'

 const productList = () => {
    fetch(URL + '/ProductList') // It shows the error is here
      .then((response) => response.json())
      .then((data) => {
        settingResults(data);
        console.log(' fetch settingResults' + data);
      });
  };

Error:

Access to fetch at 'http://localhost:63579/WebService.asmx/ProductList' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

net::ERR_FAILED

My Chrome broswer and Visual Studio errors are in Hebrew and I can't change the language English , many people has tried but non received the answer how to do it.

Error (translated):

Application server error '/'.
The application template is not recognized for a URL that ends unexpectedly in '/ ProductList'.

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,686 questions
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,542 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,128 questions
0 comments No comments
{count} votes

5 answers

Sort by: Most helpful
  1. Michael Taylor 55,501 Reputation points
    2021-08-03T14:18:54.007+00:00

    This is a CORS issue. CORS is what prevents a malicious user from injecting code into your web app that does something on a remote server without your knowledge. CORS is a security feature of the browser. When enabled (and it should be) your app is limited to talking to the URLs that you approve or in the same domain. This prevents someone from injecting additional scripts.

    The specific error here is that your web app appears to be hosted at localhost:3000 but the web service you're calling is at localhost:63579. Since the domains are different CORS blocks the call for security reasons. The correct workaround is to go into your app's CORS configuration (happens at startup in ASP.NET) and add the domain(s) you want your app to communicate without outside the app's URL. Since this is environment-specific you'll most likely want to put this info into your config file and load it at runtime based upon the environment. You can read how to do that here.

    1 person found this answer helpful.

  2. AgaveJoe 28,876 Reputation points
    2021-08-03T17:56:14.33+00:00

    ASMX is not a REST service as explained several times in your other recent threads. Configure ASMX to handle CORS and REST. Uncomment the [System.Web.Script.Services.ScriptService] in the code behind.

    Add the following service protocols to web.config for HTTP GET and POST.

      <system.web>
        <compilation debug="true" targetFramework="4.7.2" />
        <httpRuntime targetFramework="4.7.2" />
        <webServices>
          <protocols>
            <add name="HttpGet"/>
            <add name="HttpPost"/>
          </protocols>
        </webServices>
      </system.web>
    

    The following configuration adds the CORS headers to the HTTP responses from the ASMX services. It is important to understand that ASMX existed well before React.

      <system.webServer>
        <httpProtocol>
          <customHeaders>
            <add name="Access-Control-Allow-Headers" value="accept, content-type" />
            <add name="Access-Control-Allow-Origin" value="https://localhost:44363"/>
            <add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS" />
          </customHeaders>
        </httpProtocol>
      </system.webServer>
    

    The Access-Control-Allow-Origin value is the domain making the HTTP request. Use the React client application domain.

    As explained in your other threads, Web API is a far better choice for modern frameworks like React because most service APIs expect a JSON response and REST documented services. ASMX returns XML/SOAP and uses WSDL documentation services. React APIs expect REST documentation not XML.

    According to your previous threads and code, the ASMX service returns XML that contains an embedded JSON string. This is due to serializing the response twice. You'll need to create an XML doc and extract the JSON string from the XML doc. Then convert the JSON string to a JSON object.

    fetch('http://localhost:63579/WebService.asmx/ProductList')
        .then(response => response.text())
        .then(xml => (new window.DOMParser()).parseFromString(xml, "text/xml").documentElement.firstChild.textContent)
        .then(jsonStr => JSON.parse(jsonStr))
        .then(data => console.log(data));  
    

    IMHO, it is much easier to return application/json content when implementing a React solution.

    1 person found this answer helpful.

  3. Yijing Sun-MSFT 7,086 Reputation points
    2021-08-04T06:46:34.157+00:00

    Hi @Elado ,
    When a browser receives a non-simple HTTP request, the CORS protocol requires the browser to send a preflight request to the server and wait for approval (or a request for credentials) from the server before sending the actual request. therefore, a REST API resource needs to implement an OPTIONS method that can respond to the OPTIONS preflight request with at least the following response headers mandated by the Fetch standard:

    • Access-Control-Allow-Methods
    • Access-Control-Allow-Headers
    • Access-Control-Allow-Origin

    Let's suppose we are making a POST request to a fictional JSON API at https://api.example.com with a Content-Type of application/json. The preflight request would be like this:

    OPTIONS / HTTP/1.1  
    Host: api.example.com  
    Origin: http://localhost:8100  
    Access-Control-Request-Method: POST  
    Access-Control-Request-Headers: Content-Type  
    

    If the server is CORS enabled, it will parse the Access-Control-Request-* headers and understand that a POST request is trying to be made from http://localhost:8100 with a custom Content-Type.The server will then respond to this preflight.
    If the returned origin and method don't match the ones from the actual request, or any of the headers used are not allowed, the request will be blocked by the browser and an error will be shown in the console. Otherwise, the request will be made after the preflight.Since the API expects JSON, all POST requests will have a Content-Type: application/json header and always be preflighted. So, I suggest your ASMX service need to return JSON format.

    Best regards,
    Yijing Sun


    If the answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our  documentation  to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

  4. daowdos 296 Reputation points
    2021-08-05T14:13:57.957+00:00

    @AgaveJoe

     [WebMethod]  
        public string AddProduct(Product product)  
        {  
            return BLL.AddProduct(product);  
        }  
    

    BLL.cs

    public static string AddProduct(Product product)
    {
    int addProduct = DAL.AddProduct(product);
    return new JavaScriptSerializer().Serialize(addProduct);
    }

    WebService
    AddProduct

    examination
    The test form is only available for service operations that include basic data types as parameters.

    This is why I pass parameters to the SQL

    waste of time
    just a huge waste, and another week with errors.


  5. Jenny Tran 1 Reputation point
    2021-09-07T14:22:00.33+00:00

    Hey, have you resolved this issue? There are 3 suggestions for your case:

    1. If you can deploy both server and frontend in the same domain, it works well and no need to fix any things, because you are accepted by CORS policy.
    2. If you need to deploy to 2 domain and there is no issue with privacy on your server side, and you can managed server side, just enable allow CORS for your server side. (Install-Package Microsoft.AspNet.WebApi.Cors).
    3. If the server side can't enabled "allow CORS", you need to make a proxy on your frontend like this video: https://youtu.be/4B5WgTiKIOY

    Hope it help.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.