Is there a way I can choose where ASP.MVC places my form validation errors? - asp.net-mvc-4

I am using ASP.NET MVC 4 HTML.BeginForm and it creates a validation-summary-errors class as
below. This doesn't fit with my layout. Is there a way that I can make it put the
validation div class in a different place?
<form action="/User/Account/Login" method="post" novalidate="novalidate">
<div class="validation-summary-errors">
<ul>
<li>The user name or password provided is incorrect.</li>
</ul>
</div>
<fieldset>
<legend>Local Login</legend>
<ol>
<li>ation-summary-errors in a different position?

Well, sure, it's up to you to put the #Html.ValidationSummary() helper call which generates this markup wherever you want. As far as controlling the exact markup that this helper spits, that would be much more difficult because this helper offers you almost no control over the generated markup.
If you need to have more control you could write a custom helper.

You can use #Html.ValidationMessage("validation-errors") and put it in any HTML tag and then can use CSS to give it a style.

Related

Provide IntelliSense / Validation for custom Tag Helper

Is it possible to provide IntelliSense information and validation for the parameters passed to a custom Tag Helper?
Sample
<div the-controller="Home" the-action="WrongActionName"></div>
I want to mark the-action as invalid as it does not exist in the Controller HomeController for example.
In addition I want to get the same IntelliSense experience for the-controller and the-action as build in Tag Helpers, e.g.
<form asp-controller="Home" asp-action="Index">
<!--the form content -->
</form>

why use asp-controller and asp-action if it is not compulsory

#model Task3.Models.NewUser
<form action="" method="post">
<label>first Name </label>
<input type="text" placeholder="enter name" name="firstName"/>
<input type="text" placeholder="enter last name" name="lastName"/>
<button type="submit">Submit</button>
</form>
This code works even without asp-controller and asp-action. Why should I use those then?
The tag helpers asp-controller and asp-action can be used to automatically generate a target URL but you don’t have to use them. All they do is automatically generate the href attribute for links and action attributes for forms. If you want to fill in thos values manually, there is nothing that’s stopping you from doing that.
However, using the tag helpers has a clear benefit: The actual URL that you have to use depends on various things that affect your application’s routing. So if you use manual values, you have to take that into account. And if your routing changes (for whatever reason), you have to manually update the URLs throughout your templates.
By using the tag helpers, you are attaching the target location to something that is usually rather static: A controller action. So that way, you decouple the template from your routing configuration.
One more note for form actions specifically: If you do not specify a form action, the browser will automatically post to the current URL. So if you have a POST handler on the same route as the form, then you can totally omit the action and depend on that behavior.

Aurelia eating my Bookmarks

I am working on a legacy application that is being rewritten using Aurelia, the application has a bunch of static html in a tblHelp that needs to be displayed. I am using innerhtml.bind on a div in my view to databind the stored static HTML into the view. Each record is essentially a document complete with a full table of contents that links to other divs within the document (Bookmarks).
Something like:
<div id="toc">
<h1>Table of Contents</h1>
<ul>
<li>Section 1<li>
<li>Section 2<li>
</ul>
</div>
<div id="section1">
<h2>Section 1</h2>
<p>Paragraph Text...</p>
<p>Back to Table of Contents</p>
</div>
<div id="section2">
<h2>Section 2</h2>
<p>Paragraph Text...</p>
<p>Back to Table of Contents</p>
</div>
When I display the resulting page in my Aurelia view and click on the links, rather than moving to the proper Div on the current page, it seems to be attempting to route to an unknown route and ends up returning to the home page (that is my unknown route behavior). How do I make the Aurelia Router know that I am just moving around the same page and do not require it to route to another page?
I think you need to change your <div id= to <a id= which is the correct syntax for anchors. Hopefully Aurelia will recognize them as legitimate anchors when formatted correctly.
Also, since an anchor tag shouldn't wrap the whole content, you'll just open and close it at the top of the div. You can even leave the divs there but should not duplicate the id.
Update:
That being said, I created a GistRun that actually demonstrates that Aurelia should be able to handle the <div id= anchor targets. So, I'm not exactly sure why you're having problems.
Maybe this GistRun or the more standard <a id= approach will help you.

What is the advantage of using Tag Helpers in ASP.NET Core MVC

I just come across a good write up for a new ASP.NET Core feature called Tag helpers.
From there, I understood that one can replace the following code:
#model MyProject.Models.Product
#using (Html.BeginForm())
{
<div>
#Html.LabelFor(m => p.Name, "Name:")
#Html.TextBoxFor(m => p.Name)
</div>
<input type="submit" value="Create" />
}
with:
#model MyProject.Models.Product
#addtaghelper "Microsoft.AspNet.Mvc.TagHelpers"
<form asp-controller="Products" asp-action="Create" method="post">
<div>
<label asp-for="Name">Name:</label>
<input asp-for="Name" />
</div>
<input type="submit" value="Save" />
</form>
There's some new syntax such as asp-controller, asp-for, etc. But what does it do? And what's the advantage of this new approach?
The most important improvement I've seen so far is the control it guarantees over your HTML elements. While convenient, the Html helpers used by MVC create problems when you try to do things they weren't built for.
A simple example can be seen when using the TextBox in MVC5:
#Html.TextBoxFor(m => p.Name)
The resulting HTML markup looks like:
<input class="form-control" id="Name" name="Name" type="text" value="">
Nice and simple. But what if you want to add a placeholder attribute? What if you want to use bootstrap's validation states? What if you have some 3rd party super cool javascript library which needs custom attributes. None of these things were possible in the initial release of MVC5. Though they were eventually added via update in the form of htmlAttributes. Even now adding custom attributes is kludgey at best.
#Html.TextBoxFor(m => p.Name,
new {#class="form-control has-error", placeholder="Enter Name",
superCoolFeature="Do something cool"})
While you could argue this is still less code that straight HTML, it is no longer a significant advantage. Worse, this solution still doesn't cover dashes in attributes which are fairly common. If you need them you are stuck with a workaround such as ActionLink htmlAttributes
I've gone down the route of fixing these deficiencies with custom editors, and tried building my own TextBox controls. It became obvious pretty quickly that replacing the included TextBox templates would require a lot of work. Worse, your templates have to have knowledge of any extensions you are adding to use them.
It seems like the inclusion of Bootstrap and other 3rd party tools into MVC have made it more obvious that the current design has problems with extending HTML which need to be fixed. Hopefully the tag helpers implementation is complete enough that we can avoid them in the future.
Not to mention, your Web Designers will have real HTML tags to edit that they recognize to re-design your pages. Designers shouldn't have to be coders and there's enough for these sharp folks to keep up with, studying the moving targets of HTML5 and CSS3 specs.
A few things come to mind:
As #ChrisWalter points out, these tag helpers give HTML tags an Open/Closed quality. Rather than just letting you write extension methods for common HTML patterns, you can extend an HTML element. This lets you pick-and-mix multiple extensions per component, rather than having to choose between them.
HTML Helpers tend to not work super well for elements that need to have inner HTML provided as an argument. They came up with a clever pattern so you can say:
#using (Html.BeginForm(...)){
{
<input ... />
}
But there's nothing about BeginForm() that would force you to put it in a using statement, and there's nothing to prevent you from using incorrect HTML structure. (<input> technically isn't allowed to be directly inside a <form> tag.)
This gives us a really easy transitional stepping stone into the Web Components world of HTML5. A component that you write today for jQuery or Bootstrap to pick up and enhance may make more sense as an Angular 2 or Polymer component in a few years. Using HTML syntax makes it possible to write your HTML the way you want it to look when it's a web component, and have it automatically translated into the structure it has to take on for now (or for specific browsers, later).
Accepted answer is correct but just a correction.
Html Helpers cover dashes in attributes by use of underscore. for example if you want html like
my-attr=value
then you can use html helpers like
#Html.TextBoxFor(m=>m.id,
new { my_attr = value })
then it will convert accordingly.
I know the original question asks about advantages but for the sake of completeness I have to mention one disadvantage:
With tag-helpers enabled you cannot inject C# code inside tag attributes.
I.e. this code will break:
<!-- this won't work -->
<input class="#GetMyClass()">
<!-- this won't work too -->
<input type="checkbox" #(condition ? "checked" : "") >
To work around this problem you can use custom tag helpers or just disable tag helpers altogether like described in this answer: https://stackoverflow.com/a/65281018/56621
P.S. My humble opinion that can be safely ignored: tag helpers are "magic". And "magic" is always bad in programming. If something looks like an HTML tag, walks like a tag and quacks like a tag - then it should probably be an HTML tag. Without me knowning "oh, it's not *really* a tag".
From building a basic web app from the ground up in .NET 7/Razor pages, I haven't encountered a single instance where a tag helper has an advantage over simply coding the HTML. I don't come from an MVC background so maybe that is where the advantage lies but as seen before...Microsoft has released yet another version of wheel-reinvention that instead of making things easier for some simply adds more confusion to others.

Passing Form fields which have been generated by User Control

I'm having real troubles passing form data from a posting page made up of User Controls.
I posted this question before, here, Getting form field names on Submit when form is user control but the answers have not solved my problem, or I have mis-understood them.
Let me try explaining what I am doing more clearly.
I have a page which displays a form to the user. The form is made of several sections, but for simplicity we'll say there are two. Each of these sections is a User Control, thus the actual markup for newSale.aspx is just:
<%# Page Language="VB" MasterPageFile="~/MasterPage.master" CodeFile="newSale.aspx.vb" Inherits="newSale_Default"%>
<%# Register TagPrefix="controls" TagName="customerForm" Src="~/Controls/customerForm.ascx" %>
<%# Register TagPrefix="controls" TagName="itemList" Src="~/Controls/itemList.ascx" %>
<asp:content id="content1" ContentPlaceHolderID="mainContent" runat="server">
<div class="content">
<form id="newSale" method="post" action="saveSale.aspx">
<h1>--- New Sale ---</h1>
<div class="section" id="customerSection">
<controls:customerForm ID='customerForm1' showBankDetails="false" runat='server' />
</div>
<div class="section" id="saleSection">
<controls:itemList ID='itemList1' showShipping="false" showDeposit="false" runat='server' />
<div class="row submitRow">
<div id="submitSale">Submit</div>
</div>
</div>
</form>
</div>
</asp:content>
So you see my two main Controls tags with the IDs "customerForm1" and "itemList1" respectively.
The submit button is deliberately a clickable div and submission is done by jQuery, thus:
$('#submitSale').live('click', function () { $('#newSale').submit(); });
As the User Controls are rendered into the browser, the IDs and Names of the elements are messed about (I understand the reason why) by ASP.NET, so taking one field as an example:
A field named "name" contained within the customerForm control becomes m$mainContent$customerForm1$name
'm' - being the ID of my MasterPage
'mainContent' - being the ID of the PlaceHolder
'customerForm1' - being the ID of the User Control and
'name' being the element's actual name.
I wish to submit this form to a separate file (saveSale.aspx) as per the action attribute of my Form tag declared above.
Within the Code-Behind of saveSale.aspx I need to save the data passed from the form into a dataBase and return it in the aspx file as an HTML page.
How do I reliably get the value of the submitted form fields in saveSale.aspx(.vb)?
<%= request.form("m$mainContent$customerForm1$name") %>
Works, but naturally is a pain to use, especially when I want to replicate this to other purposes.
m.mainContent.customerForm1.name.selectedValue()
tells me that 'm' is not declared
and from the other replies to my previous question I have tried registering the controls at the top of the (saveSale.aspx) page, and explicitly posting the Control into the page again with
<controls:customerForm ID='customerForm1' showBankDetails="false" runat='server' />
Which doesn't work, but even if it did, it makes no sense anyway as I don't want to use the Control anymore, I just want to get the data from it.
I do apologise if I'm being dumb here, but I have tried so many different variations of code and Googled ideas, but I can't seem to make this work in any scalable fashion beyond the Request.Form example above.
I am using .NET 2.0 so can't use the Static Client feature that I've seen mentioned for .NET 4.0
Also, please, I am using VB.NET, so if you can help, please help with a VB example.
Many thanks.