简体   繁体   中英

Why is the input specified in Begin.Form being ignored?

Below is a very simple MVC triplet, implemented to try the things out.

It seems to work except the bit new { id = Model.StatusCode } in View, which is supposed to take the current value of Model.StatusCode and pass it as the parameter to the controller. It always pass '200', the initial value of the StatusCode (numeric value of 'Model.StatusCode'), although I change the value in the input field before hitting Submit button. How can I change my code to fix it?

I need to pass the parameter to the controller as string id since thsi controller's action is also used in routing.

Model

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();
    }
}

View

@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>
}

Controller

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());
    }

}

The overload you are using Html.BeginForm will append the routevalues to the form action attribute value. So the markup of your form will be like

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

When the form is posted, Model binder/Route engine will map the 200 value to the Id parameter because it matches our default route configuration {controllername}/{actionname}/{id} . That is the reason you are getting the initial value but not the updated value from form.

What you should do is use change the name of the input field rendered by Html.EditorFor helper method to match to the action parameter name ( Id ) . so that it will overwrite the values in the Url. You can use a different overload of the EditorFor method for that. You can totally get rid of the routevalues param from your BeginForm call since your form is going to post a field with name Id .

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

This will render the input field with the name property value "Id" and when you post the form, The current value of this field will be mapped to your action method parameter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM