0

I'm using .NET CORE 1.1.0 was able to assign and read cookies from the middleware as:

app.Run(async context =>
{
    context.Response.Cookies.Append("se_id","5");
    Console.WriteLine(context.Request.Cookies["se_id"]);

    await _next.Invoke(context);  
});

But when I tried to do the same from the Controller I did not get anything done, the cookie is neither written nor is read.

I tried in the controller to use the below as well, but did not work:

namespace ApiCall.Controllers
{
    [Route("api/[controller]")]
    public class FetchController : Controller
    {
        [HttpPost]
        public JsonResult Post([FromBody]object loginParam)
        {
            Response.Cookies.Append("id2","8");
            Console.WriteLine(Request.Cookies["se_id"]);

        }
    }
}

What is the difference between handling the cookie in the middleware and handling it in the controller

UPDATE

I updated my code based on the feedback given in the comments, I noticed the below: 1. The controller is writing to the request that is coming from the server. 2. The controller did not write to the request that is coming from External file

the updated code I've is:

controller.cs:

using System;    // for Console.WriteLine
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;  // for Controller, [Route], [HttpPost], [FromBody], JsonResult and Json

namespace server
{
    [Route("api/[controller]")]
    public class ResinsController : Controller{

        [HttpGet]
        public JsonResult Get(){
           #region
              var result = new List<Item>();
              result.Add(new Item{Code = "320"});
           #endregion
         Response.Cookies.Append("id2", "8");
         Console.WriteLine(Request.Cookies["id2"]);
         return Json(result);
        }
    }

    public class Item{
        public string Code { get; set; }
   }
}

The above code is working fine, once I call it from http://localhost:60000/api/Resins

But not working when I call it from external file, the external file is working file in terms of fetch as I received the returned value, and can see it in the concole, what is not working is handling the cookies, my index.html is:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <h2>
        Test page for using ajax call in webapi core.
    </h2>
    <button onclick="useFetch()">Use Fetch</button>

    <script type="text/javascript">
        function useFetch() {
            fetch('http://localhost:60000/api/Resins', {
                method: 'get'
            }).then(function(response) {
                return response.json();
            }).then(function(returnedValue) {
                var value = returnedValue;
                console.log(value);
            }).catch(function (err) {
                console.log(JSON.stringify(err));
            });
        }
    </script>
</body>                                           
</html>

if required, the program.cs file is:

using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Hosting;  // for WebHostBuilder()

namespace server{
    public class Program{
        public static void Main(string[] args){
            Console.WriteLine("Hello World!");
            #region Define Host
            var host = new WebHostBuilder()
                .UseKestrel()
                .UseUrls("http://localhost:60000", "https://localhost:60001")
                .UseStartup<Startup>()   // Startup is the class name, not the file name
                .Build();
            #endregion

        host.Run();
        }
    }
}

the startup.cs file is:

using Microsoft.Extensions.DependencyInjection;  // for IServiceCollection
using Microsoft.AspNetCore.Builder;   // for IApplicationBuilder and FileServerOptions
using Microsoft.AspNetCore.Hosting;  // for IHostingEnvironment

namespace server{
    public class Startup{
        public void ConfigureServices(IServiceCollection services){
            services.AddCors();  // to be accesssed from external sites, i.e. outside the server
            services.AddMvc();   // to use Controllers, Add framework services.
        }
        public void Configure(IApplicationBuilder app, IHostingEnvironment env){
            app.UseCors(builder =>   // to be accesssed from external sites, i.e. outside the server
                        builder.AllowAnyOrigin()
                               .AllowAnyHeader()
                               .AllowAnyMethod()
                               .AllowCredentials()
                        );
            app.UseMvc();          
        }
    }
}

and the project.json file is:

{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {
    "Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
    "Microsoft.AspNetCore.Mvc": "1.1.0"
  },
  "frameworks": {
    "netcoreapp1.1": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.1.0"
        }
      },
      "imports": "dnxcore50"
    }
  }
}

UPDATE 2

While checking the different screens in the browser developer tool, I found the attached: 1. The Application screen mention clearly there are no cookies, 2. The Network -> Cookies screen shos the cookie had been written correctly, but the controller can not read it back, which means the controller trying to read the cookie from the Application cookies not from the Network cookies

enter image description here

Hasan A Yousef
  • 22,789
  • 24
  • 132
  • 203
  • Aren't you just using a different id (**id2** vs **se_id**), or is it just a typo in the question? Have you checked the response headers sent to the browser/fiddle/whatever? I tried 1.1 and had no trouble setting cookies in a controller using `Response.Cookies.Append` the same way you did – Daniel J.G. Nov 21 '16 at 10:41
  • @DanielJ.G. it is not typo, I just tried creating agitato cookie and read the old one, I could not read the already made one, and could not create new one, I checked in the browser developer tool, the 'id2' cookie, never got create, can you please share with me your test file that worked with you, as zip folder, so I look into it, may it help figuring something wrong somewhere. Thanks – Hasan A Yousef Nov 21 '16 at 16:45
  • I created a new project in VS, upgraded to 1.1 and used pretty much your controller. Check [this gist](https://gist.github.com/DaniJG/ac1e54579985efe96718fc70b0f1a069) – Daniel J.G. Nov 21 '16 at 17:12
  • Thanks @DanielJ.G. Kindly see my update to the question. – Hasan A Yousef Nov 23 '16 at 05:25

1 Answers1

0

I found guidelines from this post, where the issue looks to be related to the request in the external html file, not to the controller programming, and as mentioned here:

XmlHttpRequest responses from a different domain cannot set cookie values for their own domain unless withCredentials is set to true before making the request, regardless of Access-Control- header values

In my code, it worked after adding the credentials: 'include' to the fetch so my original code became like:

fetch('http://localhost:60000/api/Resins', {
      credentials: 'include',
      method: 'get'
}).then(function(response) {
      return response.json();
}).then(function(returnedValue) {
      var asdf = returnedValue;
      console.log(asdf);
}).catch(function (err) {
     console.log(JSON.stringify(err));
});

and cookies can now be read from the controller, though in the browser developer tool, still can be seen under network -> Cookies and nothing appearing under Application -> cookies.

enter image description here

Community
  • 1
  • 1
Hasan A Yousef
  • 22,789
  • 24
  • 132
  • 203