Why does normal markup inside an @Using Html.Begin

2019-06-25 09:04发布

问题:

related: MVC3 Razor using Html.BeginForm problem

When I make an HTML form for MVC 3/VB with the Razor engine, I would expect to be able to do it like this:

@Using Html.BeginForm("Action", "Controller")
    <fieldset>
        @* Other form code and values *@
    </fieldset>
End Using

But if I do that I get "BC32035: Attribute specifier is not a complete statement. Use a line continuation to apply the attribute to the following statement." I need to add an @ character before the opening tag to avoid this error. Can someone explain why?

回答1:

When using Razor with C#, what you describe is possible, because parser can determine the transition from code to markup because of the explicit '<' characters in html is not a valid C# token. VB.NET supports inline XML directly in code, so the Razor parser cannot determine that you have transitioned back to markup, so you have to be more explicit.



回答2:

I believe in Razor beginform should be like this, ie with curly braces:

@using (Html.BeginForm())
{
    @* Other code here *@
}


回答3:

I don't use VB.NET, but I think you should do this:

@Using Html.BeginForm("Action", "Controller")
    @:<fieldset>
        @* Other form code and values *@
    @:</fieldset>
End Using

With VB.NET's first-class supports for XML, it treats tags as XML, hence it treats fieldset(any HTML tags for that matter) as XML too; and XML as being part of language of VB.NET, it will run counter to Razor's parser

A quick trip on VS2010 using ASP.NET MVC for VB.NET, this would suffice:

@Using Html.BeginForm("Action", "Controller")
    @<fieldset>
        @* Other form code and values *@
    </fieldset>
End Using

VB.NET's language literal XML support run afoul of Razor's parser, just prevent it with adding extra @ or @:



回答4:

For multi-line support, as pointed out in Using in Razor VB.net MVC not work as expected, you can use @<text>...</text> to switch back to "text mode" and output html like this:

@Using Html.BeginForm("Action", "Controller")
    @<text>
      <fieldset>
        * Other form code and values *
      </fieldset>
    </text>
End Using