基于Http Header值的ASP.NET MVC5 / 6路由

时间:2015-07-16 16:21:10

标签: c# asp.net asp.net-mvc-5 asp.net-mvc-routing asp.net-core-mvc

假设我有一个最基本的控制器

public class HomeController : Controller
{
    public ActionResult Index(string id, string language)
    {
        return View();
    }
}

其中包含2个参数。但是,有一个要求是,调用action方法的客户端应该从URL传递id值,而从http头传递language值。这意味着网址应为/Home/Index/12345,同时调用客户端将设置Http标头值language : en

如何在MVC5或MVC6中设置路由以达到要求?

请不要提供来自Web Api的样本。

由于

2 个答案:

答案 0 :(得分:7)

有一个属性FromHeaderAttribute。从其文档:

  

指定应使用的参数或属性绑定   请求标题。

您应该能够将其添加到控制器的语言参数中。默认情况下,它将查找与参数同名的标头,但它还有一个name参数,可用于指定其他名称,例如:

public ActionResult Index(string id, [FromHeader(Name="Accept-Language")]string language)
{
    return View();
}

您还可以查看位于github MVC repo的测试网站 ModelBindingWebSite 。检查名为FromHeader_BlogController的控制器。

PS 查看HeaderModelBinder的源代码,它似乎可以用于绑定字符串和数组(假设标题有逗号分隔的值列表)

答案 1 :(得分:0)

Daniel J.G.所述,您可以将Controller操作参数绑定到FromHeaderAttribute。但请记住,Controller可以直接访问Request.Headers。可以更好地省略Controller的语言参数并通过属性访问值作为枚举:

  public enum LanguageType
  {
     Unknown = -1,
     English,
     Spanish,
     German,
     Chinese
  }

  public LanguageType Language
  {
     get
     {
        string langStr = Request.Headers["Accept-Language"];
        switch (langStr.ToLower())
        {
           case "english":
              return LanguageType.English;
           case "spanish":
              return LanguageType.Spanish;
           case "german":
              return LanguageType.German;
           case "chinese":
              return LanguageType.Chinese;
           default:
              return LanguageType.Unknown;
        }
     }
  }