Html.BeginForm 在区域后自动添加子文件夹
Posted
技术标签:
【中文标题】Html.BeginForm 在区域后自动添加子文件夹【英文标题】:Html.BeginForm is automatically adding a sub-folder after the area 【发布时间】:2020-06-04 05:49:13 【问题描述】:我在我的 ASP.NET MVC 应用程序中创建了一个名为 B2b
的区域,并且我还在该区域下创建了一个名为 Shopify
的子文件夹:
为了注册Shopify
子文件夹,我创建了一个CustomViewEngine
如下(followed this tutorial):
public class ExpandedViewEngine : RazorViewEngine
public ExpandedViewEngine()
var extendedViews = new[]
"~/Areas/B2b/Views/Shopify/1/0.cshtml",
;
var extendedPartialViews = new[]
"~/Areas/B2b/Views/Shopify/Shared/0.cshtml"
;
ViewLocationFormats = ViewLocationFormats.Union(extendedViews).ToArray();
PartialViewLocationFormats = PartialViewLocationFormats.Union(extendedPartialViews).ToArray();
这是我的区域注册码(我使用的是lowercase-dashed-route):
public class B2bAreaRegistration : AreaRegistration
public override string AreaName
get
return "B2b";
public override void RegisterArea(AreaRegistrationContext context)
// this route is for controllers and views inside Shopify sub-folder
var shopifyDefaultRoute = new LowercaseDashedRoute(
"B2b/Shopify/controller/action/id",
new RouteValueDictionary(new controller = "ProductMap", action = "Display", id = UrlParameter.Optional ),
new DashedRouteHandler(),
this,
context,
new[] "Shopless.Web.Areas.B2b.Controllers.Shopify"
);
context.Routes.Add("Shopify_default", shopifyDefaultRoute);
// default area route which is not under Shopify subfolder
var b2bDefaultRoute = new LowercaseDashedRoute(
"B2b/controller/action/id",
new RouteValueDictionary(new action = "index", id = UrlParameter.Optional ),
new DashedRouteHandler(),
this,
context,
new[] "Shopless.Web.Areas.B2b.Controllers"
);
context.Routes.Add("B2b_default", b2bDefaultRoute);
我在 Global.asax 中注册了上述内容:
protected void Application_Start()
ViewEngines.Engines.Add(new ExpandedViewEngine());
AreaRegistration.RegisterAllAreas();
// more code ...
一切正常,以下代码除外:
@using (Html.BeginForm("update", "organisation", new area = "B2b" , FormMethod.Post))
<input type="text" id="name" name="name">
正在生成以下 HTML:
<form action="/b2b/shopify/organisation/update" method="post" novalidate="novalidate">
<input type="text" id="name" name="name">
</form>
请注意,它在我的地区名称后添加了shopify
, B2b
。上面的表格在B2b
区域内,但不在shopify
子文件夹下,所以不知道为什么要添加它?
【问题讨论】:
它正在打这个路由模板"B2b/Shopify/controller/action/id"
@Nkosi:路由按预期工作,我的意思是,如果我将 url:B2b/Controller/Action/Id
放在浏览器中,它会命中正确的控制器......如果我把 B2b/Shopify/Controller/Action/Id
放在浏览器,它会在shopify子文件夹中执行正确的操作...但我不知道为什么Html.BeginForm
总是在它生成的url中包含shopify
子文件夹(当我在该区域内使用它时)
当浏览确定它会工作时,BeginForm 正在生成一个 URL,所以这是不同的。等待现在发布答案
【参考方案1】:
它映射到此路由模板"B2b/Shopify/controller/action/id"
,因为它还匹配在为表单生成 URL 时提供给 BeginForm
的常规值。
对于 URL 生成,两个区域路由约定相互冲突。
如果我要求路由表生成一个 URL,我给它一个 controller、action 和 area。给定同一区域内的以下路线模板,哪条路线将首先匹配
B2b/Shopify/controller/action/id
B2b/controller/action/id
而且由于第一场比赛总是赢,它会映射到上面的第一场比赛,这将解释你的表格的当前体验。
如果您想使用特定路由为表单生成 URL,请使用 BeginRouteForm
Method
@using (Html.BeginRouteForm(
routeName: "B2b_default",
routeValues: new action = "update", controller = "organisation", area = "B2b" ,
method: FormMethod.Post)
)
<input type="text" id="name" name="name">
【讨论】:
非常感谢...我明白如何解决问题了。我不确定我是否理解你的第一句话,BeginForm
形式如何匹配这两种约定?是不是因为我在区域注册中定义了2个约定?
您的两个区域路由约定在生成 URL 时相互冲突。如果我要求生成一个 URL,并且我给路由表一个控制器、动作和区域,那么哪个路由会首先匹配?
所以它无法根据表单所在的路径找出正确的约定?这是我的假设......
@HoomanBahreini 不。它取决于你给予什么。您可能会发布到位于该区域之外的表单,因此它不会假定您的意思是在当前表单的同一位置。如果您不提供路线值,它将仅默认为当前位置。以上是关于Html.BeginForm 在区域后自动添加子文件夹的主要内容,如果未能解决你的问题,请参考以下文章
使用 javascript 将路由值传递给 Html.BeginForm
使用 onsubmit 属性时 request.files 返回 null