c# - ASP.NET MVC 表单 - 返回具有先前表单值的 View 的正确方法是什么?

标签 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>
}

Controller :

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

最佳答案

好的,所以我使用了您的代码并使用 View 模型快速实现了 Controller 操作。请注意,我在某些 View 模型属性的顶部有数据注释属性,这样我们就不必手动验证 num1 和 num2 是否实际上是数字。

View 模型:

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

}

Controller (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>
}

请注意,现在您的表单字段可以强类型化到表单中的 View 模型中。 ASP.NET MVC 的模型绑定(bind)系统只是将发布的表单字段填充到发布 Controller 操作上的 View 模型实例中。您甚至不需要手动匹配字段。而且您也不必再使用 Viewbag。

另请注意,在后 Controller 操作中,我检查了第二个数字是否为零,将错误直接添加到 ModelState 以及结果 View 中,因此您会看到错误消息在看法。您最初将错误消息放在结果 View 中(所以我保留了它),但您可能会考虑仅通过 ModelState 对象添加任何错误处理消息,而不是填充结果文本框。您还可以在 WCF 服务中检查除以零的情况。另一种选择是创建自定义数据注释来检查是否被零除。希望这会有所帮助。

关于c# - ASP.NET MVC 表单 - 返回具有先前表单值的 View 的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38032916/

相关文章:

javascript - 禁用子项时向容器添加工具提示

javascript - Web请求检查服务器

c# - 不再支持使用旧密码进行身份验证,请使用 4.1 样式密码

javascript - SignalR 在 IE 和 Firefox 上与 POST 请求断开连接

c# - 包含引用类型的结构

c# - ASP.Net Core 中的 JSON 序列化/反序列化

html - 鼠标悬停时文本字段输入焦点

jquery - 使用 CSS 更改移动设备上的 HTML 布局

c# - 在 MVC 中的同一 View 上显示列表并提交表单

c# - ASP.Net Core API 访问 HttpRequestMessage