2015-12-18 67 views
0

下面是一个非常简单的MVC三元组,用于实现这些功能。为什么Begin.Form中指定的输入被忽略?

它似乎工作,除了在视图中的位new { id = Model.StatusCode },它应该取当前值Model.StatusCode并将其作为参数传递给控制器​​。它始终通过'200',即StatusCode的初始值('Model.StatusCode'的数值),尽管在点击Submit按钮之前更改了输入字段中的值。我如何更改我的代码来修复它?

我需要将参数传递给控制器​​作为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()); 
    } 

} 

回答

1

您使用超载会将路由值附加到action属性值的形式。所以你的形式的标记会像

<form action="Error/StatusCode/200"> 
    <input type="text" name="StatusCode" /> 
</form> 

当表单被提交,因为它符合我们的默认路由配置{controllername}/{actionname}/{id}型粘合剂/路由引擎将映射200价值的Id参数。这就是您获取初始值的原因,但不是从表单中更新的值。

您应该做的是使用更改由Html.EditorFor辅助方法呈现的输入字段的名称以匹配操作参数名称(Id)。以便它将覆盖Url中的值。您可以为EditorFor方法使用不同的重载。由于您的表单将发布名称为Id的字段,因此您可以完全摆脱BeginForm调用中的路径值参数。

@using (Html.BeginForm("StatusCode", "Home" ,FormMethod.Post, null)) 
{ 
    @Html.EditorFor(model => model.Name,null,"Id") 
    <input type="submit" /> 
} 

,这会使得与属性值“ID”输入字段,当您发布的形式,该字段的当前值将被映射到你的动作方法的参数。

+0

我不确定隐藏字段是否会执行,我需要一个可见的输入字段,以便用户可以更改它的值 –

+0

然后将其更改为文本框(input type ='text') – Shyju

+0

您能解释它为什么是更好/它与@ Html.EditorFor有什么不同?另外,你所建议的构造不会明确地采用StatusCode并将其作为'string id'传递;这项工作是隐含的吗? –