Duplicated ID in ManageLogin.cshtml built-in template - asp.net-mvc

I am using the built-in template which comes with ASP.NET MVC 4. The View which is causing problem is: ManageLogins.cshtml
This is how the output looks like:
So, this particular user has connected both Google and Facebook external IDs to his account:
And this is the Built in MS Template which produces the above code (I have changed the appearance a bit, but the code is the same)
#foreach (var account in Model.CurrentLogins)
{
<div class="form-row">
#using (Html.BeginForm("RemoveLogin", "Manage"))
{
#Html.AntiForgeryToken()
<div>
#Html.Hidden("loginProvider", account.LoginProvider)
#Html.Hidden("providerKey", account.ProviderKey)
<input type="submit" class="btn btn-default" value="Remove" title="Remove this #account.LoginProvider login from your account" />
</div>
}
</div>
}
The problem is that this code generates 2 inputs with id=loginProvider, and this gives me the browser error:
How can solve this problem?

Since model binding occurs on name and not id, I decided to remove the id from the hidden field and just use the name attribute:
#using (Html.BeginForm("RemoveLogin", "Manage", FormMethod.Post, new { #class = "inline-form float-right" }))
{
#Html.AntiForgeryToken()
<div>
<input type="hidden" name="LoginProvider" value="#Model.LoginProvider" class="d-none login-provider" />
<input type="hidden" name="ProviderKey" value="#Model" class="d-none provider-key" />
<input type="submit" class="btn btn-default" value="Remove" title="Remove this #account.LoginProvider login from your account" />
</div>
}

You can use an overload of the helper that allows you to provide htmlAttributes.
e.g.
for (int i = 0; i < 3; i++)
{
#Html.Hidden("foo", $"value{i}", new { id = $"foo{i}"})
...
}
Caveat: while the sample above shows how you can do whatever you want for name, value, id, etc., it may affect validation (and force you to customize that too). In your specific use case however, since it's just id, it should be fine.

Related

Is it possible to include a file with a form POST

I got a regular POST in my mvc app:
#using (Html.BeginForm("Update", "AController", FormMethod.Post))
{
<div style="margin-bottom:20px"></div>
#Html.AntiForgeryToken()
<div class="form-input">
<input class="form-control" type="text" name="#(nameof(Model.Name))" value="#(Model.Name)" />
</div>
<br />
<div class="form-input">
<input class="form-control" type="text" name="#(nameof(Model.Name2))" value="#(Model.Name2)" />
</div>
<br />
<div>
<input type="file" name="Image" id="Image" name="#(nameof(Model.Image))" value="#(Model.Image)" />
</div>
<button type="submit" class="btn btn-primary btn-sm">TEXT HERE</button>
}
Now when doing the submit the two regular text fields gets binded the model but the file does not.
After some reading it seems like the upload part should be in a separate form, is that correct?
I really want to avoid having two different POST as it does not fit the design of the page.
You should be able to get the posted file from the Request directly in the controller with following code
if(Request.Files.Count > 0)
{
var file = Request.Files[0];
...
}
But you need to add the multipart/form-data to your form
#using (Html.BeginForm("Update", "AController", FormMethod.Post, new { enctype="multipart/form-data" }))
Check What does enctype='multipart/form-data' mean? for reference on the multipart/form-data

POST and GET in the same form created by BeginForm method

How to create a form that has a search function (pull data from the database) AND a submit function (add data to the database) at the same time using the BeginForm() method? I am reviewing the overloads on MSDN and I don't seem to find one.
Code:
#using (Html.BeginForm()){
<table>
#*Bunch of textboxes and dropdown lists*#
</table>
<div id=" buttonHolder">
<input id="Search" type="button" value="Search" />
<input id="Reset1" type="reset" value="Reset" />
<input id="Submit1" type="submit" value="Add" />
</div>
}
You can use two approaches here:
handle onsubmit and fetch/save data with AJAX (you can do it even with Html.BeginForm but it's easier to go just with regular <form ...)
#using (Html.BeginForm("DoIt", "DoItAction", FormMethod.Post, new { onsubmit = "submitWithAjax(event); return false;" }))
create two separate forms with a different action/controller pair

Login MVC redirect to another page

I have a log-in page. When the user hits the log-in button the button will calla another action method. that action method will have two parameter. the user provided userid and password. then it do some validation and redirect to another action method according to the outcome. I am struggling with there. i guess this is pretty simple. i am new to MVC. Any help would be appriciated.
View
<div class="container-fluid">
<div class="starter-template">
<h1>Policy Assessment Tool</h1>
<p class="lead">Are You Following Right?</p>
<button type="button" class="btn btn-primary btn-lg" onclick="location.href='#Url.Action("Create","UserDatas")'">Register for a An Account</button>
<h3><strong>OR</strong></h3>
</div>
<div class="row">
<form class="form-signin" role="form" method="post">
<div class="col-lg-4"></div>
<div class="col-lg-4">
<h2 class="form-signin-heading">Please Sign-In to Continue</h2>
<div class="input-group">
<input type="text" name="input_domain_id" class="form-control text-center" placeholder="Domain ID" autofocus required>
<input type="password" name="input_domain_password" class="form-control text-center" placeholder="Domain Password" required>
<div class="col-lg-12">
<p><button class="btn btn-lg btn-primary btn-block" type="submit" onclick="location.href='#Url.Action("Verify_Login", "Ldap_Login_Verify")'">Login</button></p>
</div>
</div><!-- /input-group -->
</div><!-- /.col-lg-4 -->
<div class="col-lg-4"></div>
</form>
</div><!-- /.row -->
</div>
Controller
[HttpPost]
public ActionResult Verify_Login(string input_domain_id, string input_domain_password)
//Log-in Logic
return View("Success")
Instead of using form tag use Html.BeginForm HtmlHelper and pass Model from Controller to View for the best practice. Here is link for you to get Getting Started With MVC5.
Based on the mark up above you need not worry about it, When the form is posted the values will get bound to the parameters of the action method, As the parameter names are similar to the form field names.
The above concept is called model binding. The below two links should give you a good idea on the same.
http://www.codeproject.com/Articles/710776/Introduction-to-ASP-NET-MVC-Model-Binding-An-Absol
http://dotnetslackers.com/articles/aspnet/Understanding-ASP-NET-MVC-Model-Binding.aspx
I have tried to compile a simple example below.
Lets assume there is a view like below.
#model string
#{
ViewBag.Title = "Injection";
}
<h2>Injection</h2>
#using(Html.BeginForm())
{
<div id="formDetails">
#Html.TextBox("UserName")
</div>
<div>
<input type="submit" id="btnTest" value="Click Me" />
</div>
}
The Action method for the same would be like
[HttpPost]
public ActionResult Injection(string UserName)
{
return View("Injection");
}
So when i click on the submit button, The form is posted , Since the ViewName is injection, and there is a corresponding action method called injection it will automatically hit that action method. Since the parameter name of the method and field is the same, What ever value is there in the username textbox will get automatically bound to the method parameter.

Fixings Cross Site Scripting (Reflected) in ASP.Net MVC

I have been using the Zed Attack Proxy (ZAP) to test a new application being developed. The App is ASP.NET MVC4 based using the standard HTML helpers where ever possible.
ZAP has identified the following alert:
Cross Site Scripting (Reflected)
GET: localhost:65227/CashReceipt?SearchText=javascript%3Aalert%281%29%3B
On this page we have a list of receipts and a search box whereby a user can search by receipt number.
When this page is called using the link above, the following Razor builds the relevant part of the page:
#using (Html.BeginForm("Index", "CashReceipt", FormMethod.Get, new { #class = "form-inline", #role = "form" }))
{
<div class="form-group">
<label class="hidden-label" for="SearchText">Search For</label>
#Html.TextBoxFor(m => m.SearchText, new { #class = "form-control input-lg", #placeholder = "Receipt Number" })
</div>
<input type="submit" value="Search" class="btn btn-primary btn-lg" />
}
the HTML generated is:
<input class="form-control input-lg" id="SearchText" name="SearchText" placeholder="Receipt Number" type="text" value="javascript:alert(1);" />
The page rendered appears as:
This does not result in an actual alert box being displayed within the browser, just the text is reflected back.
Is this an XSS issue that needs to be resolved? If so, how?
No it is not an XSS issue since the javascript alert is not executed. Razor Html helpers properly encode and decode text to stop this from happening by default.

ASP.NET MVC Create querystring from form

I am trying to create a simple search box that results in something like http://www.example.com/Search?s=searchTerm I have the routing setup so that it accepts a url like this, and does the right thing. The problem I'm having is getting the form to create the querystring. I have tried many variations of:
<% using (Html.BeginForm("Search", "Home", FormMethod.Get, new { ???? })) {%>
<input id="submitSearch" class="searchBox" type="text" runat="server"/>
<input type="submit" value="Search" /> <%} %>
I'm not sure how to setup the Html.BeginForm so it grabs the submitSearch value and passes it to /Search?s=valueHere. This seems like I am missing something easy.
You need to set name on the input box to s.
<% using (Html.BeginForm("Search", "Home", FormMethod.Get, new { })) { %>
<input id="s" name="s" class="searchBox" type="text" />
<input type="submit" value="Search" />
<% } %>
Also, note that I changed the id to s as well, since common practice is to have the same value for name and id. However, it is only the name attribute that affects the query string name in the request.
And as David noted in a comment, the runat="server" is not needed in ASP.NET MVC.

Resources