4

Can someone explain to me why we need to use

@using (Html.BeginForm("CheckUser", "Home", FormMethod.Post))

Instead of :

@Html.BeginForm("CheckUser", "Home", FormMethod.Post)

What is the main purpose of @using in here, as far as I know, I only use 'using' keyword to make sure that the object is disposed as soon as it goes out of scope. I am a little confused.

I am asking this question because @Html.BeginForm outputs a text : "System.Web.Mvc.Html.MvcForm {" before rendering the content of the form. And by using the 'using' keyword this text is not rendered.

Edit: This is my code that renders the "System.Web.Mvc.Html.MvcForm ..."

@Html.BeginForm("CheckUser", "Home", FormMethod.Post)
    <label for="username">Username :</label>
    <input type="text" name="username" id="username" placeholder="username"/>

    <label for="password">Password :</label>
    <input type="password" name="password" id="password" placeholder="password"/>

    <input type="submit" value="Submit" />
@{Html.EndForm();}
Mehdi Souregi
  • 3,153
  • 5
  • 36
  • 53
  • 3
    that is to generate corresponding closing tag (in this case the closing
    tag)
    – Thangadurai Jan 20 '17 at 10:00
  • I am not convinced yet, why we need to use the using keyword ? – Mehdi Souregi Jan 20 '17 at 10:01
  • 3
    The output of the closing tag is implemented by the dispose method. By not using 'using' you would not have a closing '' tag. – mstaessen Jan 20 '17 at 10:03
  • Why without using the 'using' keyword the output is "System.Web.Mvc.Html.MvcForm { ..." ? and we also have the closing tag ? – Mehdi Souregi Jan 20 '17 at 10:21
  • Possible duplicate of [@Html.BeginForm Displaying "System.Web.Mvc.Html.MvcForm" on Page](http://stackoverflow.com/questions/4975354/html-beginform-displaying-system-web-mvc-html-mvcform-on-page) – romanoza Jan 20 '17 at 10:41
  • The answer is here: http://stackoverflow.com/a/4975908/3901618 – romanoza Jan 20 '17 at 10:42
  • Nope, it is different, I don't want the solution, I know that using keyword is working fine, i just want to know what goes behind the scene – Mehdi Souregi Jan 20 '17 at 10:43
  • 1
    @Souregi, You can always inspect the [source code](https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/FormExtensions.cs) –  Jan 20 '17 at 10:45

3 Answers3

3

BeginForm has a rather interesting (mis)use of the IDisposible pattern!

Starting at the beginning, BeginForm returns an instance of MvcForm. MvcForm implements IDisposible and its Dispose method...

[...] renders the closing tag at the end of a Using statement.

(source: https://msdn.microsoft.com/en-us/library/system.web.mvc.html.mvcform.dispose(v=vs.118).aspx#M:System.Web.Mvc.Html.MvcForm.Dispose)

Without this sort of implementation you would need to do something along the lines of

@{ Html.BeginForm("CheckUser", "Home", FormMethod.Post); }
<!-- form content here -->
@{ Html.EndForm(); }

Which, I guess, they made the decision would be clunky and easy to forget.

Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • Thanks for the @{Html.EndForm();}, this is first time I hear of about it, But it still renders "System.Web.Mvc.Html.MvcForm { ..." – Mehdi Souregi Jan 20 '17 at 10:25
  • 1
    @Souregi, Both the `BeginForm()` and `EndForm()` need to be wrapped in `@{ ... }` because they return `void` (Jamiec, I took the liberty of editing your answer to show the correct syntax - and `EndForm()` does exist :) –  Jan 20 '17 at 10:39
  • thump up for Stephen Muecke it is clear for me now :) – Mehdi Souregi Jan 20 '17 at 10:41
3

by using @using (Html.BeginForm("CheckUser", "Home", FormMethod.Post))

It automatically adds </form> in your page. you don't need to care about closing your form tag and it prevents accidental issue if somebody forgets to close the form.

@*<form>*@
    @using (Html.BeginForm("CheckUser", "Home", FormMethod.Post)) 
    {

    }@* </form> gets added automaticaly*@ 

If you want to use Html.EndForm(), use it like following

@{Html.BeginForm("CheckUser", "Home", FormMethod.Post);}
//other form elements
@{Html.EndForm();}

Reason: Html.EndForm() doesn't returns anything( return type void), it write on the stream in stead. If you don't use {}, @ symbol will expect something to return from the following statement hence it will use object.ToString() which results into System.Web.Mvc.Html.MvcForm

K D
  • 5,889
  • 1
  • 23
  • 35
  • I used the @Html.EndForm but it still renders "System.Web.Mvc.Html.MvcForm " before rendering the content of the form. – Mehdi Souregi Jan 20 '17 at 10:26
  • use it like this @{Html.EndForm();} – K D Jan 20 '17 at 10:28
  • yes, i used this form actually @{Html.EndForm();}, the @Html.EndForm did not work for me :) .But it still renders "System.Web.Mvc.Html.MvcForm " – Mehdi Souregi Jan 20 '17 at 10:30
  • your begin form statement should also be like @{Html.BeginForm(...)} can you paste your html along with these helpers in your question? – K D Jan 20 '17 at 10:33
  • yeah, you have not added Begin form correctly. check the usage in my answer again and try – K D Jan 20 '17 at 10:37
3

This is a trick to force rendering of the close tags of the form.

The trick is based on the IDisposable interface, which using understands and uses to call the Dispose method after the block has ended.

The Dispose implementation of the type returned from BeginForm actually doesn't dispose anything. It just writes the closing tag to the output stream.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325