ASP.NET MVC表单 - 使用以前的表单值返回视图的正确方法是什么?

时间:2016-06-25 20:58:37

标签: c# html asp.net asp.net-mvc razor

我有一个实现WCF服务的任务,并从任何类型的客户端调用它。我已经有了一些控制台,winform,WPF应用程序的经验,所以我想用它来学习ASP.NET MVC。

我知道我还没有正确实现它的“M”部分,但是我想知道在表单上处理数据的正确方法是什么才能更新显示结果而不是我所拥有的(工作)到目前为止:

查看:

@using (Html.BeginForm("UseSimpleMathClient", "Home"))
{
    <div style="width:450px">
        <table style="width:100%">
            <tr><td><h4>@Html.Label("First number", new { @for = "num1" })</h4></td> <td> @Html.TextBox("num1", ViewData["num1"])</td></tr>
            <tr><td><h4>@Html.Label("Second number", new { @for = "num2" })</h4></td> <td> @Html.TextBox("num2", ViewData["num2"])</td></tr>
            <tr>
                <td colspan="2">
                    <h2 style="text-align:center">
                        <input type="submit" name="operation" value="+" />
                        <input type="submit" name="operation" value="-" />
                        <input type="submit" name="operation" value="*" />
                        <input type="submit" name="operation" value="÷" />
                    </h2>
                </td>
            </tr>
            <tr>
                <td colspan="2"><b>@Html.Label("Result")</b> &nbsp; @Html.TextBox("result", ViewData["result"], new {disabled = "disabled", style="min-width:80%;text-align:center" })</td>
            </tr>
            </table>
    </div>
}

控制器:

      public ActionResult USeSimpleMathClient(char operation)
    {
        float num1, num2;
        float? result = null;

        if (!float.TryParse(Request.Form[0], out num1) || !float.TryParse(Request.Form[1], out num2))
        {
            ViewData["result"] = "Please enter valid numbers before selecting an operation.";
        }
        else
        {
            switch (operation)
            {
                case '+':
                    result = mathClient.Add(num1, num2);
                    break;
                case '-':
                    result = mathClient.Subtract(num1, num2);
                    break;
                case '*':
                    result = mathClient.Multiply(num1, num2);
                    break;
                case '÷':
                    if (num2 != 0)
                        result = mathClient.Divide(num1, num2);
                    break;
                default:
                    break;
            }

            ViewData["result"] = result != null ? String.Format("{0} {1} {2} = {3}", num1, operation, num2, result) : "You can't divide by zero!";
        }

        ViewData["num1"] = Request.Form[0];
        ViewData["num2"] = Request.Form[1];
        return View("Index");
    }

1 个答案:

答案 0 :(得分:1)

好的,所以我接受了你的代码并使用viewmodel快速实现了你的控制器动作。请注意,我在某些视图模型属性的顶部有数据注释属性,因此我们不必手动验证num1和num2实际上是否为数字。

视图模型:

public class SimpleMathVM
{
    [Required(ErrorMessage = "Please enter valid numbers before selecting an operation.")]
    [Display(Name = "First number")]
    public float Num1 { get; set; }


    [Required(ErrorMessage = "Please enter valid numbers before selecting an operation.")]
    [Display(Name = "Second number")]
    public float Num2 { get; set; }

    public string Result { get; set; }

    public char Operation { get; set; }

}

控制器(GET和POST操作):

    public ActionResult USeSimpleMathClient()
    {
        return View("Index");
    }


    [HttpPost]
    public ActionResult USeSimpleMathClient(SimpleMathVM viewModel)
    {

    //I moved the checking for zero up here, that way you could immediately return the view. 
    //I kept your version where you populate the Result textbox with the error message,
    //but really you should probably only add the error message to the ModelState.

        if (viewModel.Num2 == 0 && viewModel.Operation == '÷')
        {
            ModelState.AddModelError(string.Empty, "You can't divide by zero!");
            viewModel.Result = "You can't divide by zero!";

        //You can pick which one of the above two lines work better for you.
        //Usually adding error messages to the ModelState is the way to go.
        }

        if (!ModelState.IsValid)
        {
            return View("Index", viewModel);
        }

        switch (viewModel.Operation)
        {
            case '+':
                viewModel.Result = mathClient.Add(viewModel.Num1, viewModel.Num2).ToString();
                break;
            case '-':
                viewModel.Result = mathClient.Subtract(viewModel.Num1, viewModel.Num2).ToString();
                break;
            case '*':
                viewModel.Result = mathClient.Multiply(viewModel.Num1, viewModel.Num2).ToString();
                break;
            case '÷':
                viewModel.Result = mathClient.Divide(viewModel.Num1, viewModel.Num2).ToString();
                break;
            default:
                break;
        }

        return View("Index", viewModel);
    }

查看:

//must bring in the View Model so you can access the MVC lambda helpers below
@model WebApplication11.Models.SimpleMathVM

@using (Html.BeginForm("UseSimpleMathClient", "Home"))
{
//You can use ValidationSummary to display object level model errors,
//such as the division by zero error we directly added to the ModelState
//in the controller
@Html.ValidationSummary(true);

<style type="text/css">
    .navbar {
        display: none !important;
    }

    body {
        padding: 0px 0px 0px 0px !important;
    }
</style>
<div style="width:450px">
    <table style="width:100%">
        <tr><td><h4>@Html.LabelFor(x => x.Num1)</h4></td> <td> @Html.TextBoxFor(x => x.Num1)</td><td> @Html.ValidationMessageFor(x => x.Num1)</td></tr>
        <tr><td><h4>@Html.LabelFor(x => x.Num2)</h4></td> <td> @Html.TextBoxFor(x => x.Num2)</td><td> @Html.ValidationMessageFor(x => x.Num2)</td></tr>
        <tr>
            <td colspan="2">
                <h2 style="text-align:center">
                    <input type="submit" name="operation" value="+" />
                    <input type="submit" name="operation" value="-" />
                    <input type="submit" name="operation" value="*" />
                    <input type="submit" name="operation" value="÷" />
                </h2>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <b>@Html.LabelFor(x => x.Result)</b> &nbsp; @Html.TextBoxFor(x => x.Result, new { disabled = "disabled", style = "min-width:80%;text-align:center" })
                @Html.ValidationMessageFor(x => x.Result)
            </td>
        </tr>
    </table>
</div>
}

请注意,现在您的表单字段可以强烈输入到表单中的视图模型中。 ASP.NET MVC的模型绑定系统只是将发布的表单字段填充到post控制器操作上的视图模型实例中。您甚至不必进行匹配字段的手动工作。而且你也不必再使用Viewbag了。

另请注意,在post控制器操作上,我检查第二个数字是否为零,将错误直接添加到ModelState,还添加到Results视图,因此您将看到错误消息显示两次视图。您最初将错误消息放在结果视图中(所以我保留了这一点),但您可以考虑仅通过ModelState对象添加任何错误处理消息,而不是在结果文本框中填充。您还可以在WCF服务中检查除零。另一种选择是创建自定义数据注释以检查除以零。希望这会有所帮助。