Hasan A Yousef Hasan A Yousef - 9 days ago 5
C# Question

Assign cookie from controller to external html file

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

Answer

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

Comments