布局中的表单:剃刀页面

Posted

技术标签:

【中文标题】布局中的表单:剃刀页面【英文标题】:Form in Layout: Razor Pages 【发布时间】:2019-07-04 09:35:05 【问题描述】:

我的网络应用程序布局中有一个form 中的select,需要从每个页面访问。该表单设置了在每个页面上加载数据所需的会话变量。

<form asp-page-handler="CustomerChange" method="post" class="navbar-form navbar-left">
    <select name="Customer" id="Customer" class="form-control" onchange="this.form.submit()">
        <option value="">Select Customer</option>
        <option value="Vand">Vandalay</option>
        <option value="Kram">Kramerica</option>
    </select>
</form>

我知道我可以创建一个基础 PageModel 并在每个页面上继承该基础以响应 OnPost 例如

public abstract class BaseSecurePageModel : PageModel

    [BindProperty]
    public string Customer  get; set; 
    public virtual void OnPostCustomerChange()
    
        HttpContext.Session.SetString("Customer", Customer);
    

但这并不适合将模型绑定到表单,并且还要求我记得从每个页面中的基类继承。是否有正确的方法来处理需要随处可用的表单?

【问题讨论】:

您应该使用 ViewComponent,如本答案所述:***.com/questions/53104614/… 【参考方案1】:

尝试改用控制器并让您的 CustomerChange ActionResult 指定 [Route()]。我在剃须刀页面中为我的大部分布局项目(例如购物车、本地化等)使用了控制器,并且效果很好。

// 根据 Steven B 的反馈更新答案。

下面是我上面谈到的本地化示例。表单触发针对 BaseController.cs 中的 SetLanguage 方法的帖子

在 _Layout.cshtml 文件中,我有一个局部视图:

@Html.Partial("_SetLanguagePartial") // Used prior to .net core 2.1

<partial name="_SetLanguagePartial" /> // Used for .net core 2.1+

这个 _SetLanguagePartial.cshtml 里面的 html 包含一个带有相应的 asp-controller 和 asp-action 的表单

 <form id="selectLanguage" asp-controller="Base" asp-action="SetLanguage" asp-route-returnUrl="@returnUrl" method="post" class="form-horizontal" role="form">
    <ul class="list-inline">
      @foreach (var culture in cultureItems)
      
         var countryIcon = "usa.png";
         <li>
             <button type="submit" class="btn btn-sm btn-link" name="culture" title="@culture.Text" value="@culture.Value">

               @switch (culture.Text)
               
                  case "Japanese" :
                       countryIcon = "japan.png";
                       break;
                   case "Spanish" :
                       countryIcon = "spain.png";
                       break;
                   default:
                       break;
                

                 <img src="@Configuration["BlobStorage:StorageUrl"]/images/@countryIcon" />
               </button>
          </li>
       
   </ul>
</form>

BaseController.cs

[Route("[controller]/[action]")]
        public class BaseController : Controller
        
            [HttpGet]
            public IActionResult GetCartViewComponent()
            
                return ViewComponent("Cart");
            

            [HttpPost]
            public IActionResult SetLanguage(string culture, string returnUrl)
            
                Response.Cookies.Append(
                    CookieRequestCultureProvider.DefaultCookieName,
                    CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
                    new CookieOptions  Expires = DateTimeOffset.UtcNow.AddYears(1)
                );

                return LocalRedirect(returnUrl);
            
        

【讨论】:

这基本上就是我最终要做的。如果您在答案中添加示例表单和 ViewComponent,以便下一个人拥有完整代码,我将接受此作为答案。

以上是关于布局中的表单:剃刀页面的主要内容,如果未能解决你的问题,请参考以下文章

从剃刀页面调用方法

剃刀页面视图模型类中的 Url.Action 备用

模型不会从剃刀页面中的 _Layout.cshtml 页面中的 _Footer.cshtml 部分视图绑定

MVC和同一项目.net核心中的剃刀页面区域

无法使用锚标记帮助程序使剃刀页面路由工作

如何从我的视图的 javascript 访问我的代码隐藏文件中的 JsonResult 变量?剃刀页面。 C#