布局中的表单:Razor Pages
Form in Layout: Razor Pages
我的 Web 应用程序布局中的 select
中有一个 form
,需要从每个页面访问它。表单设置了一个在每个页面上加载数据所需的会话变量。
<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);
}
}
但这并不适合将模型绑定到表单,还需要我记得在每个页面中从基础 class 继承。是否有正确的方法来处理需要随处可用的表单?
尝试改用控制器并让您的 CustomerChange ActionResult 指定 [Route()]。我对我的大部分布局项目(例如购物车、本地化等)使用控制器...在 razor 页面中效果很好。
// 根据 Steven B 的反馈更新了答案。
下面是我上面谈到的本地化的一个例子。该表单针对 BaseController.cs
中的 SetLanguage 方法触发 post
在 _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" alt="@culture.Text"/>
</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);
}
}
我的 Web 应用程序布局中的 select
中有一个 form
,需要从每个页面访问它。表单设置了一个在每个页面上加载数据所需的会话变量。
<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);
}
}
但这并不适合将模型绑定到表单,还需要我记得在每个页面中从基础 class 继承。是否有正确的方法来处理需要随处可用的表单?
尝试改用控制器并让您的 CustomerChange ActionResult 指定 [Route()]。我对我的大部分布局项目(例如购物车、本地化等)使用控制器...在 razor 页面中效果很好。
// 根据 Steven B 的反馈更新了答案。
下面是我上面谈到的本地化的一个例子。该表单针对 BaseController.cs
中的 SetLanguage 方法触发 post在 _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" alt="@culture.Text"/>
</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);
}
}