Дальше откроем файл 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"
На страничке "_Layout.cshtml" указывается общая структура сайта (та часть сайта, которая повторяется на всех страничка, например меню)
Теперь запустите приложение (клавиша F5), убедитесь что оно работает и открылась страничка с надписью Calc
Следующим шагом напишем html вид нашего калькулятора. Он будет состоять из двух текстовых полей для аргументов и выпадающего списка для выбора действия. Так же на страничке будет кнопка для передачи данных на сервер. Результат действий будем выводить в тег "<span>"
Этим правилом мы привязали url "Home/Result.aspx" к действию "Result" контроллера "Home". Это действие будет у нас обрабатывать математические функции.
Теперь изменим html вид калькулятора. Мы добавим тег <form> в котором укажем на какой url передавать введенные аргументы (передавать будем на "Home/Result.aspx")
Поставим breakpoint на этом методе, что бы увидеть какие данные передались. Запустим приложение, введем 2+2, нажмем "="
Как Вы можете увидеть два аргумента передались, а математическое действие нет. Для этого нужно изменить выпадающий список. Нужно указать его название, это делается с помощью атрибута "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>
Запустим приложение и проверим, все ли правильно у нас считает.
Если все работает, то перейдем к улучшению кода.
Для начала хочу обратить Ваше внимания, что мы в двух местах указали 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
Теперь обратите внимание на то, что после подсчета какой-то функции, наш url становиться очень длинным (например, http://localhost:62442/Home/Result.aspx?arg1=2&math=%2B&arg2=2). Для того что бы этого избежать будем передавать данные на сервер методом POST, а не GET, который используется по-умолчанию. Для этого подправим код тега <form>. Новый код: <form action="@Url.Action("Result", "Home")" method="post" >
Что бы избежать писанины, и возможных ошибок, рекомендую тег <form> заменить на такой C# код: вместо тега <form> пишем @using(Html.BeginForm("Result", "Home")) { , а вместо закрития </form> пишем }
Так же обратите внимание, что у нас используется два действия "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..."
Назовем класс 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):
Как Вы видете, в текстовые поля мы записываем введеные аргументы 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);
}
Запустите приложение и проверьте, что все правильно работает.
Не работает Не удалось найти имя типа или пространства имен "Calculator" (пропущена директива using или ссылка на сборку?)