2015-12-02 2 views
1

Я все еще участвую в процессе обучения MVC, который длится долгое время с помощью Web Forms. Одна из вещей, которую я пытаюсь понять, - это подходящий способ связать кнопку/вход с помощью ActionResult.Уточнение при подключении кнопки вверх к ActionResult

Одним из проектов, которые я использовал в качестве примера, является Университет Contoso. В этом проекте у них есть CourseController, а на странице Course/Edit.cshtml они используют форму, которая не указывает контроллер или метод действий. Поэтому я не совсем понимаю, как форма знает, куда ей нужно перейти, поскольку ни форма, ни кнопка не указывают на метод контроллера/действия. Это потому, что страница называется Edit, а ActionResult также называется Edit?

Это Contoso .cshtml и ActionResult в контроллере.

@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form-horizontal"> 
     <h4>Course</h4> 
     <hr /> 
     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
     @Html.HiddenFor(model => model.CourseID) 

     <div class="form-group"> 
      @Html.LabelFor(model => model.CourseID, new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.DisplayFor(model => model.CourseID) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Credits, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.Credits, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Credits, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      <label class="control-label col-md-2" for="DepartmentID">Department</label> 
      <div class="col-md-10"> 
       @Html.DropDownList("DepartmentID", null, htmlAttributes: new { @class = "form-control" }) 
       @Html.ValidationMessageFor(model => model.DepartmentID, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Save" class="btn btn-default" /> 
      </div> 
     </div> 
    </div> 
} 

[HttpPost, ActionName("Edit")] 
     [ValidateAntiForgeryToken] 
     public ActionResult EditPost(int? id) 
     { 
      if (id == null) 
      { 
       return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
      } 
      var courseToUpdate = db.Courses.Find(id); 
      if (TryUpdateModel(courseToUpdate, "", 
       new string[] { "Title", "Credits", "DepartmentID" })) 
      { 
       try 
       { 
        db.SaveChanges(); 

        return RedirectToAction("Index"); 
       } 
       catch (RetryLimitExceededException /* dex */) 
       { 
        //Log the error (uncomment dex variable name and add a line here to write a log. 
        ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator."); 
       } 
      } 
      PopulateDepartmentsDropDownList(courseToUpdate.DepartmentID); 
      return View(courseToUpdate); 
     } 

Также еще одна вещь, я нашел с некоторого поиска является разработчики вызовом метода контроллера/действия в форме, а также указывает на метод контроллер/действие непосредственно в кнопке или ввода.

Здесь вы добавляете его в форму.

@using (Html.BeginForm("SignUp", "Account", FormMethod.Post)) 
{ 
    <!-- form goes here --> 

    <input type="submit" value="Sign Up" /> 
} 

Здесь находится непосредственно в этой кнопке.

<button type="button" onclick="location.href='@Url.Action("MyAction", "MyController")'" > 

Есть ли какие-либо преимущества/недостатки в использовании любого из этих методов? Мне кажется более понятным, если вы поместите элемент управления/метод в форму декларации или непосредственно на кнопку.

ответ

2

Это просто разные overloads из BeginForm метод.

@using (Html.BeginForm()) {} будет отображать тег формы, где значение атрибута action установлено на текущую страницу. Это означает, что если вы рендеринг страницы создания (сообщение/Create), Эта перегрузка будет оказывать по указанному ниже HTML

<form action="/Post/Create" method="post"></form> 

По умолчанию, BeginForm сделает тэг формы со значением методы, установленным как «POST».

Вторая перегрузка позволяет явно указать целевое значение действия

Так что если у вас есть код ниже внутри вашего Создать вид бритвы (Post/Create)

@using (Html.BeginForm("Edit", "Post")) 
{ 
    <input type="text" name="postName" /> 
} 

Это рендер

<form action="/Post/Edit" method="post"> 
    <input type="text" name="postName" /> 
</form> 

Вам необходимо убедиться, что у вас есть метод действий, украшенный атрибутом [HttpPost], чтобы обрабатывать отправку формы в вашем контроллере

[HttpPost] 
public ActionResult Edit(string postName) 
{ 
//to do : Do something useful 
    return View(); 
} 

У нас есть еще один overload, который позволяет нам указать метод проводки формы в явном виде. По умолчанию POST, и вы можете использовать эту перегрузку, чтобы изменить его, чтобы получить (но 99% времени, вы будете использовать тип POST.)

@using (Html.BeginForm("Edit","Post",FormMethod.Get)) 
{  
} 

Вы можете увидеть все доступные перегрузкам here.Попробуйте разные и посмотрите вывод html, созданный этими (вы можете сделать «просмотр источника» на странице).

Наконец, форма будет отправлена ​​в действие цели, когда вы нажмете кнопку отправки внутри формы.

Это означает, что вам не нужно (и не должны делать это в нормальных случаях использования)

<button type="button" onclick="location.href='@Url.Action("MyAction", "MyController")'" > 

, но это достаточно

@using (Html.BeginForm("Edit", "Post")) 
{ 
    <input type="submit" /> 
} 
+0

Спасибо за объяснение. Это определенно помогает. Таким образом, в основном, поскольку образец Contoso специально не добавляет ничего в форму, он будет вытаскивать имя метода на основе имени .cshtml, и поскольку он обнаружил, что файл View в папке контроллера будет предполагать, что в качестве контроллера использовать , В противном случае, если бы я хотел, чтобы другой контроллер или имя метода из контроллера/представления, которое использовалось для отображения формы, мне нужно было бы указать это в объявлении Html.BeginForm. – Caverman

0

Каждый метод имеет ряд преимуществ 1) ActionResult имя будет отображаться в url также его непосредственный сигнал, что результат действия abd его вызов синхронизации или его прямой вызов сервера 2) @ url.action, который мы используем для относительного пути, когда-то url не распознал второй уровень для обработки тех проблем, которые мы использовали @ url.a ction для лучшего понимания для него проверка абсолютного и относительного пути 3) вы можете сделать ajax-вызов для асинхронного вызова, чтобы получить лучшую производительность. надеюсь, что это поможет вам.