Asp.net для начинающих: Пишем калькулятор на asp.net mvc

Programming
Предыдущий Следующий

Для лучшего понимания принципа обмена информацией между сайтом (Вашим браузером) и сервером напишем калькулятор.

Для начала создадим проект asp.net mvc 3.

Перейдем в файл Global.asax и удалим правило обработки url, которое создается по-умолчанию. Вместо кода:

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

пишем код

routes.MapRoute(
   "Home-Calc",
   "",
   new { controller = "Home", action = "Calc" }
);

У нас будет всего одна страничка.

Дальше откроем файл HomeController и добавляем в него событие Calc:

public ActionResult Calc()
{
    return View();
}

В папке Views/Home создаем отображение для этого действия (правой кнопкой кликаем по папке "Home", в контекстном меню выбираем "Add"->"View..."). Заполняем окно: в поле "View name" пишем "Calc"; ставим галочку "Use a layout or master page:", в поле снизу указываем путь к файлику "~/Views/Shared/_Layout.cshtml"

calc asp mvc

На страничке "_Layout.cshtml" указывается общая структура сайта (та часть сайта, которая повторяется на всех страничка, например меню)

Теперь запустите приложение (клавиша F5), убедитесь что оно работает и открылась страничка с надписью Calc

Следующим шагом напишем html вид нашего калькулятора.  Он будет состоять из двух текстовых полей для аргументов и выпадающего списка для выбора действия. Так же на страничке будет кнопка для передачи данных на сервер. Результат действий будем выводить в тег "<span>"

Открываем файл "Calc.cshtml" и пишем код:

@{
    ViewBag.Title = "Calc";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<table>
    <tr>
        <td>
            <input type="text" id="arg1" name="arg1" />
        </td>
        <td>
            <select>
                <option></option>
                <option>+</option>
                <option>-</option>
                <option>*</option>
                <option>/</option>
            </select>
        </td>
        <td>
            <input type="text" id="arg2" name="arg2" />
        </td>
        <td>
            <input type="submit" value="=" />
        </td>
        <td>
            <span></span>
        </td>
    </tr>
</table>

 Запустим приложение. На экране у Вас должна появится картинка:

asp net mvc

При нажатии на кнопку "=" ничего не происходит. Это потому, что мы не указали, куда передавать введенные данные.

Для этого в контроллер добавим действие:

public ActionResult Result()
{
    return View();
}

так же в Global.asax добавим новое правило

routes.MapRoute(
   "Home-Result",
   "Home/Result.aspx",
   new { controller = "Home", action = "Result" }
);
 

Этим правилом мы привязали url "Home/Result.aspx" к действию "Result" контроллера "Home".  Это действие будет у нас обрабатывать математические функции.

Теперь изменим html вид калькулятора. Мы добавим тег <form> в котором укажем на какой url передавать введенные аргументы (передавать будем на "Home/Result.aspx")

Новый код

<form action="/Home/Result.aspx">
<table>
    <tr>
        <td>
            <input type="text" id="arg1" name="arg1" />
        </td>
        <td>
            <select>
                <option></option>
                <option>+</option>
                <option>-</option>
                <option>*</option>
                <option>/</option>
            </select>
        </td>
        <td>
            <input type="text" id="arg2" name="arg2" />
        </td>
        <td>
            <input type="submit" value="=" />
        </td>
        <td>
            <span></span>
        </td>
    </tr>
</table>
</form>

Теперь изменим action Result, укажем что он принимает два аргумента и математическую операцию

public ActionResult Result(string arg1, string arg2, string math)
{
    return View();
}

Поставим  breakpoint на этом методе, что бы увидеть какие данные передались. Запустим приложение, введем 2+2, нажмем "="

asp net mvc

Как Вы можете увидеть два аргумента передались, а математическое действие нет. Для этого нужно изменить выпадающий список. Нужно указать его название, это делается с помощью атрибута "name":

<select name="math" >

еще раз запустите программу введите 2+2, нажмем "=" Теперь все введенные параметры передались. Нам осталось реализовать ответ сервера на наш запрос (сейчас он возвращает ошибку).

Подведем итог, что бы передать html (данные) на сервер нам нужно: обернуть его в тег form в этом теге указать url куда будут передаваться данные; данные которые мы хотим передать должны иметь атрибут "name", в котом укажем имя параметров.

 Теперь напишем обработчик введенных данных и вывод результата.

Для начала проверить, что бы аргументы arg1 и arg2 были цифрами, для этого пробуем их преобразовать в тип decimal. Используем метод decimal.TryParse. Потом в зависимости от показателя math выполним нужную операцию. Результат действия запишем в переменную result. Полный код действия Result:

public ActionResult Result(string arg1, string arg2, string math)
{
    decimal a = 0;
    decimal b = 0;
    string result ="";

    if (!decimal.TryParse(arg1, out a) || !decimal.TryParse(arg2, out b))
        result = "Не правильные аргументы";

    switch (math)
    {
        case "+":
            result = (a + b).ToString();
            break;
        case "-":
            result = (a - b).ToString();
            break;
        case "*":
            result = (a * b).ToString();
            break;
        case "/":
            result = b != 0 ?
            (a / b).ToString()
            : "error";
            break;
        default:
            result = "Выбирите математическую функцию";
            break;
    }

    return View("Calc", model: result);
}

Как видите, результат наших действий мы передали на представление "Calc" (т.е. результат будет отображаться с помощью html который находиться в файле "~/Views/Home/Calc.cshtml")

Откроем файл "Calc.cshtml" и исправим строку:

<td>
            <span></span>
</td>

на строку:

<td>
            <span>@Model</span>
</td>

Запустим приложение и проверим, все ли правильно у нас считает.

Если все работает, то перейдем к улучшению кода.

  1. Для начала хочу обратить Ваше внимания, что мы в двух местах указали url адрес "Home/Result.aspx" (в файле Global.asax и в файле Calc.cshtml) Так делать не правильно. Все url должны храниться только в Global.asax. По  этому изменим код <form action="/Home/Result.aspx"> на такой <form action="@Url.Action("Result", "Home")"> Теперь если мы изменим url  в Global.asax, то он измениться и на странички Calc.cshtml
  2. Теперь обратите внимание на то, что после подсчета какой-то функции, наш url становиться очень длинным (например, http://localhost:62442/Home/Result.aspx?arg1=2&math=%2B&arg2=2). Для того что бы этого избежать будем передавать данные на сервер методом POST, а не GET, который используется по-умолчанию. Для этого подправим код тега <form>. Новый код: <form action="@Url.Action("Result", "Home")" method="post" >
  3. Что бы избежать писанины, и возможных ошибок, рекомендую тег <form> заменить на такой C# код: вместо тега <form> пишем @using(Html.BeginForm("Result", "Home")) { , а вместо закрития </form> пишем }
  4. Так же обратите внимание, что у нас используется два действия "Calc" и "Result" и одно представление Calc.cshtml. Мы можем избавиться от действия "Result". Для этого перенесем код в метод "Calc", а Result - удалим. Так же нужно удалить правило "Home-Result" с Global.asax. И указать на странички Calc.cshtml, что данные будет обрабатывать метод Calc (<form action="@Url.Action("Calc", "Home")"> ) Полный код метода Calc:

    public ActionResult Calc(string arg1, string arg2, string math)
    {
        decimal a = 0;
        decimal b = 0;
        string result = "";

        if (!decimal.TryParse(arg1, out a) || !decimal.TryParse(arg2, out b))
            result = "введите данные";

        switch (math)
        {
            case "+":
                result = (a + b).ToString();
                break;
            case "-":
                result = (a - b).ToString();
                break;
            case "*":
                result = (a * b).ToString();
                break;
            case "/":
                result = b != 0 ?
                (a / b).ToString()
                : "error";
                break;
            default:
                result = "введите данные";
                break;
        }

        return View(model: result);
    }
     

Вы скорее всего заметили, что после нажатия на кнопку "=" все введенные данные стираются, а остается только результат. Что бы это исправить, нужно будет создать class, который мы будет передавать в файл Calc.cshtml, как результат математических действий. Для этого нажмем правой кнопкой мышки на папке "Models" и выбираем меню "Add"->"Сlass..."

asp net mvc

Назовем класс TResult. Создадим в нем свойства для аргументов и результата:

public class TResult
{
    public string arg1 {get;set;}
    public string arg2 {get;set;}
    public string math { get; set; }

    public string result { get; set; }
}

Теперь укажем, что наш файл Calc.cshtml будет принимать class TResult. Для этого вверху файла Calc.cshtml пишем код: @model Calculator.Models.TResult

После этого мы можем изменить html (полный код Calc.cshtml):

@model Calculator.Models.TResult
@{
    ViewBag.Title = "Calc";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@using (Html.BeginForm("Calc", "Home"))
{
<table>
    <tr>
        <td>
            <input type="text" id="arg1" name="arg1" value="@Model.arg1" />
        </td>
        <td>
            <select name="math" >
                <option></option>
                <option @(Model.math == "+" ? "selected='selected'" : "")  >+</option>
                <option @(Model.math == "-" ? "selected='selected'" : "")>-</option>
                <option @(Model.math == "*" ? "selected='selected'" : "")>*</option>
                <option @(Model.math == "/" ? "selected='selected'" : "")>/</option>
            </select>

        </td>
        <td>
            <input type="text" id="arg2" name="arg2" value="@Model.arg2" />
        </td>
        <td>
            <input type="submit" value="=" />
        </td>
        <td>
            <span>@Model.result</span>
        </td>
    </tr>
</table>
}
 

Как Вы видете, в текстовые поля мы записываем введеные аргументы value="@Model.arg2" и выбираем нужную математическую функцию.

Теперь изменим наше действие Calc, так что бы оно передавало класс TResult в представление:

public ActionResult Calc(string arg1, string arg2, string math)
{
    Calculator.Models.TResult vdata = new Models.TResult()
        {
            arg1 = arg1,
            arg2 = arg2,
            math = math,
        };


    decimal a = 0;
    decimal b = 0;
    string result = "";

    if (!decimal.TryParse(arg1, out a) || !decimal.TryParse(arg2, out b))
        result = "введите данные";

    switch (math)
    {
        case "+":
            result = (a + b).ToString();
            break;
        case "-":
            result = (a - b).ToString();
            break;
        case "*":
            result = (a * b).ToString();
            break;
        case "/":
            result = b != 0 ?
            (a / b).ToString()
            : "error";
            break;
        default:
            result = "введите данные";
            break;
    }

    vdata.result = result;
    return View(vdata);

}
 

Запустите приложение и проверьте, что все правильно работает.

 

 

Asp.net для начинающих. Содержание

  • В 7/10/2013 11:05:56 AM, Аноним

    Не работает Не удалось найти имя типа или пространства имен "Calculator" (пропущена директива using или ссылка на сборку?)

  • В 7/10/2013 11:23:43 AM,

    Предполагаю, что вы создали класс TResult в другом "namespace".

Самостоятельный отпуск Опыт заказа вывоза мусора в Киеве Магія зміни: Від ночі до дня
Магія Вечірнього Неба: Відлякуйте втомленість дня і зануртеся у світ загадок і краси