【问题标题】:Assign cookie from controller to external html file将 cookie 从控制器分配给外部 html 文件
【发布时间】:2017-04-04 10:50:08
【问题描述】:

我使用.NET CORE 1.1.0 能够从middleware 分配和读取cookies:

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

    await _next.Invoke(context);  
});

但是当我尝试从Controller 做同样的事情时,我什么也没做,cookie 既没有被写入也没有被读取。

我也尝试在控制器中使用以下内容,但没有奏效:

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"]);

        }
    }
}

middleware处理cookie和在controller处理cookie有什么区别

更新

我根据 cmets 中给出的反馈更新了我的代码,我注意到以下内容: 1. 控制器正在写入来自服务器的请求。 2.控制器没有写入来自External文件的请求

我更新的代码是:

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; }
   }
}

上面的代码运行良好,一旦我从http://localhost:60000/api/Resins调用它

但是当我从外部文件调用它时不起作用,外部文件在fetch 方面是工作文件,因为我收到了返回值,并且可以在concole 中看到它,不起作用的是处理@987654336 @,我的index.html是:

<!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>

如果需要,program.cs 文件是:

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();
        }
    }
}

startup.cs 文件是:

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();          
        }
    }
}

project.json 文件是:

{
  "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"
    }
  }
}

更新 2

在查看browser developer tool 中的不同屏幕时,我发现了附件: 1.Application屏幕明确提到没有cookies, 2. Network -> Cookies 屏幕显示cookie已正确写入,但控制器无法将其读回,这意味着控制器试图从Application cookies而不是Network cookies读取cookie

【问题讨论】:

  • 您不只是使用不同的 id(id2se_id),还是只是问题中的拼写错误?您是否检查过发送到浏览器/小提琴/其他的响应标头?我尝试了 1.1,并且使用 Response.Cookies.Append 在控制器中设置 cookie 没有问题
  • @DanielJ.G.这不是错字,我只是尝试创建 agitato cookie 并读取旧的,我无法读取已经制作的,也无法创建新的,我在浏览器开发人员工具中检查了 'id2' cookie,从未创建,您能否与我分享您与您一起使用的测试文件,作为 zip 文件夹,所以我查看它,它可能有助于在某处找出错误。谢谢
  • 我在 VS 中创建了一个新项目,升级到 1.1 并且几乎使用了你的控制器。检查this gist
  • 感谢@DanielJ.G。请查看我对问题的更新。

标签: c# cookies asp.net-core asp.net-core-mvc .net-core


【解决方案1】:

我从这个post 中找到了指导方针,其中问题看起来与外部 html 文件中的请求有关,而不是与控制器编程有关,正如 here 所述:

来自不同域的XmlHttpRequest 响应无法为自己的域设置cookie 值,除非在发出请求之前将 withCredentials 设置为 true,无论 Access-Control- 标头值如何

在我的代码中,将credentials: 'include' 添加到fetch 后它起作用了,所以我的原始代码变成了这样:

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));
});

现在可以从控制器中读取 cookie,尽管在浏览器开发者工具中,仍然可以在 network -&gt; Cookies 下看到,而在 Application -&gt; cookies 下什么也没有出现。

【讨论】:

    猜你喜欢
    • 2017-10-18
    • 2013-10-27
    • 2018-10-22
    • 2014-02-06
    • 2020-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多