为什么在 Begin.Form 中指定的输入被忽略?
Why is the input specified in Begin.Form being ignored?
下面是一个非常简单的 MVC 三元组,实现后可以尝试一下。
除了 View 中的 new { id = Model.StatusCode }
位外,它似乎可以正常工作,它应该采用 Model.StatusCode
的当前值并将其作为参数传递给控制器。它总是传递 '200',StatusCode 的初始值('Model.StatusCode' 的数值),尽管我在点击提交按钮之前更改了输入字段中的值。我怎样才能更改我的代码来修复它?
我需要将参数作为 string id
传递给控制器,因为该控制器的操作也用于路由。
型号
public class ErrorModel
{
[DisplayName("Status Code")]
public string StatusCode { get; set; }
public ErrorModel(string statusCode)
{
HttpStatusCode code;
if (! Enum.TryParse(statusCode, out code))
{
code = HttpStatusCode.NotFound;
}
StatusCode = ((int)code).ToString();
}
public ErrorModel(HttpStatusCode statusCode = HttpStatusCode.OK)
{
StatusCode = ((int)statusCode).ToString();
}
}
查看
@using WebApplication1.Models
@model WebApplication1.Models.ExcelModel
@using (Html.BeginForm("StatusCode", "Error",
new { id = Model.StatusCode }, FormMethod.Post, null))
{
<p>
<div class="editor-label">
@Html.LabelFor(model => model.StatusCode)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.StatusCode)
</div>
<input type="submit" value="Submit" />
</p>
}
控制器
public class ErrorController : Controller
{
static readonly List<HttpStatusCode> ErrorCodes = new List<HttpStatusCode>(){
HttpStatusCode.Unauthorized, HttpStatusCode.Forbidden, HttpStatusCode.NotFound, HttpStatusCode.InternalServerError};
public ActionResult StatusCode(string id)
{
ViewBag.Message = "";
if ((id == null) || (ErrorController.AreEqual(HttpStatusCode.OK, id)))
{
return View("StatusCode", new ErrorModel(HttpStatusCode.OK));
}
foreach (HttpStatusCode errorCode in ErrorCodes)
{
if (ErrorController.AreEqual(errorCode, id))
{
return View("HttpError", new ErrorModel(errorCode));
}
}
ViewBag.Message = "Exception " + id
+ @" is not supported, see https://msdn.microsoft.com/en-us/library/system.net.httpstatuscode(v=vs.110).aspx for further details";
return View("HttpError", new ErrorModel(HttpStatusCode.InternalServerError));
}
static private bool AreEqual(HttpStatusCode httpCode, string statusCode)
{
return (statusCode == ((int)httpCode).ToString());
}
}
您正在使用的重载 Html.BeginForm
会将路由值附加到表单 action
属性值。所以你的表单的标记就像
<form action="Error/StatusCode/200">
<input type="text" name="StatusCode" />
</form>
当表单被 posted 时,模型 binder/Route 引擎会将 200
值映射到 Id
参数,因为它匹配我们的默认路由配置 {controllername}/{actionname}/{id}
.这就是您从表单中获取初始值而不是更新值的原因。
您应该做的是使用更改由 Html.EditorFor
辅助方法呈现的输入字段的名称以匹配操作参数名称 (Id
)。这样它将覆盖 Url 中的值。您可以为此使用 EditorFor 方法的不同重载。您可以完全摆脱 BeginForm
调用中的 routevalues 参数,因为您的表单将 post 一个名称为 Id
.
的字段
@using (Html.BeginForm("StatusCode", "Home" ,FormMethod.Post, null))
{
@Html.EditorFor(model => model.Name,null,"Id")
<input type="submit" />
}
这将使用 名称 属性 值 "Id" 呈现输入字段,当您 post 表单时,当前值该字段将映射到您的操作方法参数。
下面是一个非常简单的 MVC 三元组,实现后可以尝试一下。
除了 View 中的 new { id = Model.StatusCode }
位外,它似乎可以正常工作,它应该采用 Model.StatusCode
的当前值并将其作为参数传递给控制器。它总是传递 '200',StatusCode 的初始值('Model.StatusCode' 的数值),尽管我在点击提交按钮之前更改了输入字段中的值。我怎样才能更改我的代码来修复它?
我需要将参数作为 string id
传递给控制器,因为该控制器的操作也用于路由。
型号
public class ErrorModel
{
[DisplayName("Status Code")]
public string StatusCode { get; set; }
public ErrorModel(string statusCode)
{
HttpStatusCode code;
if (! Enum.TryParse(statusCode, out code))
{
code = HttpStatusCode.NotFound;
}
StatusCode = ((int)code).ToString();
}
public ErrorModel(HttpStatusCode statusCode = HttpStatusCode.OK)
{
StatusCode = ((int)statusCode).ToString();
}
}
查看
@using WebApplication1.Models
@model WebApplication1.Models.ExcelModel
@using (Html.BeginForm("StatusCode", "Error",
new { id = Model.StatusCode }, FormMethod.Post, null))
{
<p>
<div class="editor-label">
@Html.LabelFor(model => model.StatusCode)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.StatusCode)
</div>
<input type="submit" value="Submit" />
</p>
}
控制器
public class ErrorController : Controller
{
static readonly List<HttpStatusCode> ErrorCodes = new List<HttpStatusCode>(){
HttpStatusCode.Unauthorized, HttpStatusCode.Forbidden, HttpStatusCode.NotFound, HttpStatusCode.InternalServerError};
public ActionResult StatusCode(string id)
{
ViewBag.Message = "";
if ((id == null) || (ErrorController.AreEqual(HttpStatusCode.OK, id)))
{
return View("StatusCode", new ErrorModel(HttpStatusCode.OK));
}
foreach (HttpStatusCode errorCode in ErrorCodes)
{
if (ErrorController.AreEqual(errorCode, id))
{
return View("HttpError", new ErrorModel(errorCode));
}
}
ViewBag.Message = "Exception " + id
+ @" is not supported, see https://msdn.microsoft.com/en-us/library/system.net.httpstatuscode(v=vs.110).aspx for further details";
return View("HttpError", new ErrorModel(HttpStatusCode.InternalServerError));
}
static private bool AreEqual(HttpStatusCode httpCode, string statusCode)
{
return (statusCode == ((int)httpCode).ToString());
}
}
您正在使用的重载 Html.BeginForm
会将路由值附加到表单 action
属性值。所以你的表单的标记就像
<form action="Error/StatusCode/200">
<input type="text" name="StatusCode" />
</form>
当表单被 posted 时,模型 binder/Route 引擎会将 200
值映射到 Id
参数,因为它匹配我们的默认路由配置 {controllername}/{actionname}/{id}
.这就是您从表单中获取初始值而不是更新值的原因。
您应该做的是使用更改由 Html.EditorFor
辅助方法呈现的输入字段的名称以匹配操作参数名称 (Id
)。这样它将覆盖 Url 中的值。您可以为此使用 EditorFor 方法的不同重载。您可以完全摆脱 BeginForm
调用中的 routevalues 参数,因为您的表单将 post 一个名称为 Id
.
@using (Html.BeginForm("StatusCode", "Home" ,FormMethod.Post, null))
{
@Html.EditorFor(model => model.Name,null,"Id")
<input type="submit" />
}
这将使用 名称 属性 值 "Id" 呈现输入字段,当您 post 表单时,当前值该字段将映射到您的操作方法参数。