Disable Required Validation Specific Field in the View ASP.NET MVC 4 - asp.net-mvc

if someone could give me some hint I would appreciate.
I'm searching for a while, and I even found a post I thought it would solve my problem, but it didn't.
Disable Required validation attribute under certain circumstances
Basically I have a simple User.cs model where I have username, FirstName, LastName and SignupDate
All have the required annotation and I would like to solve this without erasing the Required tag.
After I generate the view, I erase in the view the html code for the SignupDate:
<div class="editor-label">
#Html.LabelFor(model => model.SignupDate)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SignupDate)
#Html.ValidationMessageFor(model => model.SignupDate)
</div>
When I click submit it does not work.
Also if I do the suggested in the other post
<div class="editor-label">
#Html.LabelFor(model => model.SignupDate)
</div>
<div class="editor-field">
#Html.TexBoxFor(model => model.SignupDate, new { data_val = false })
</div>
If I leave it as blank also does not work..
Any suggestions? Thanks!!

You can disable client validations on the view and remove the errors on the modelstate for those entities you don't want to validate the value.
In my case I wanted to change a Password only if the user typed one. Using Html.HiddenFor was not a good approach due to sends the password to the client every time, and password shouldn't be sent.
What I did was to disable the client validations on the view
#model MyProject.Models.ExistingModelWithRequiredFields
#{
ViewBag.Title = "Edit";
Html.EnableClientValidation(false);
}
That allows me to submit the form even with empty values. Please note that all client validations are ignored, however server validations still run, so you need to clear those you don't need to be executed. In order to do this, go to the action in the controller and remove the errors for each property you need to
public ActionResult Edit(ExistingModelWithRequiredFields updatedModel)
{
var valueToClean = ModelState["RequiredPropertyName"];
valueToClean.Errors.Clear();
if(ModelState.IsValid)
{
...
//Optionally you could run validations again
if(TryValidateModel(updatedModel)
{
...
}
...
}
...
}

I think this should solve it, assuming model.SignupDate holds a value:
<%: Html.HiddenFor(model => model.SignupDate) %>

Related

ViewModel data being passed in address bar

I have my change password controler.
The user changes the password and clicks submit.
I have my viewmodel of person p.
I am not passing it at all to my success page.
return View("succsessFulLogin");
And still I am getting
http://localhost:50010/Password/ChangePassword?AccountName=username&CurrentPassword=currentPassValue&NewPassword=newPassValue&NewPasswordCheck=newCheckPassValue
In the address bar
this is my code on the page:
#using (Html.BeginForm("ChangePassword", "Password", FormMethod.Get))
{
#Html.HiddenFor(model => model.AccountName)
<br />
<div>
<h4>#Html.LabelFor(m => m.CurrentPassword)</h4> #Html.PasswordFor(m => m.CurrentPassword, new { onkeydown = "capLock(event);" } ) #Html.ValidationMessageFor(m => m.CurrentPassword)
</div>
<br />
<div>
<h4>#Html.LabelFor(m => m.NewPassword)</h4> #Html.PasswordFor(m => m.NewPassword, new { onkeydown = "capLock(event);" }) #Html.ValidationMessageFor(m => m.NewPassword)
</div>
<br />
<div>
<h4>#Html.LabelFor(m => m.NewPasswordCheck)</h4> #Html.PasswordFor(m => m.NewPasswordCheck, new { onkeydown = "capLock(event);" }) #Html.ValidationMessageFor(m => m.NewPasswordCheck)
</div>
<br />
<p>
<button class="btn-lg" type="submit">#Global.SAVE</button>
</p>
}
I disagree with osman Rahimi.
Using HTTP POST is in no way more secure than HTTP GET! As long as you're passing everything as clear text over http, you can read anything passed to and from the server, even if it isn't shown in the address bar. If you want to check me yourself, all you have to do is download fiddler, check the request and responses your page generates and see for yourself.
The proper way to transmit passwords on the net is to make sure you're using SSL and hashing the passwords. I am by no means an expert on the subject, but I think you'll find need in these answers:
Securely Transfer User Entered Password
How should password be transfered for logon in Asp.net Identity
How to securely save and send login username/password?
when you are using HTTP GET the browser send data in URl and in this way you have limitation up to 2048 characters.
know more about HTTPGET and HTTPPOST
to keep your data secure and protected change your method To POST Like this :
#using (Html.BeginForm("ChangePassword", "Password" FormMethod.Post, null))
{}
then Add [HTTpPost] to your Action Method in your controller , like :
[HttpPost]
public ActionResult ChangePassword(yourmodel model){}

asp.net core mvc application form post with query string parameters

I am building a login form in .net core mvc. Below is my login form
<form class="c-form" asp-controller="Account"
asp-action="Login">
<div class="form-group">
#Html.TextBoxFor(m => m.Username, new { #class = "form-control c-input", placeholder = "Username" })
</div>
<div class="form-group">
#Html.PasswordFor(m => m.Password, new { #class = "form-control c-input", placeholder = "Password" })
</div>
<div class="help-text help-text-error">
#Html.ValidationMessage("UserNamePasswordInvalid")
</div>
<div class="">
<button type="submit" class="btn-c btn-teal login-btn width100">Login</button>
</div>
If a form is posted with incorrect credentials user stays on the page with validation failure messages.
Login page also has return url in query string, when the form is posted query string parameters are lost. What is the correct way of doing form post in .net core.
To keep the query string when the form is submitted write a hidden field in the form containing the query string contents:
#Html.Hidden("returnUrl",#Request.QueryString)
Make sure your controller action that handles the post request has a parameter called returnUrl (or the model that is passed as a parameter has that property) and the model binding will take care of passing it through to the controller. Then in the controller action if the login is successful use that data to redirect accordingly.
I know that it's passed a lot of time, but I found a better solution for this problem.
I added a parameter called QueryString in Model as Dictionary string
in view, in tag form, add
So at this time, the post have the parameters in query string<form asp-all-route-data="#Model.QueryString"
Your controller/PageModel method must contain all parameters that you need to persist. Something like this:
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
If the controller and action pair for getting and posting the form is the same, than it is simpler to just delete asp-controller and asp-action attributes from the form opening tag, leaving your like this:
<form class="c-form" method="post">

Editor And ReadOnly Error

I have simple edit form, where you can edit user profile, but you cannot edit username.
So instead this code:
#Html.EditorFor(model => model.username)
I use this line:
#Html.TextBoxFor(model => model.username, new {disabled = "disabled", #readonly = "readonly" })
This works fine, but, I cannot save other fields which are "EditorFor"
e.g. I have column Customers, so one user can have one or more customers, so if I make change in edit, e.g. add new user to customer, and then when I click save, it does not save it. But if I change code again to #Html.EditorFor(model => model.username) then it save it...
Any idea how to fiks this?
The problem is that a read only textbox is not sent back (value is not in POSTed datas).
So if you want to have a readonly textbox AND have the value of username in POSTed datas, you'll have to add a
#Html.HiddenFor(m => m.username)
But... if you just wanna display them, you should just manage that in your controller (don't try to update username... as you don't wanna update username).

Display name instead editor field in MVC4

I have in my edit form displayed: Username, TimeZone, Customer...
I don't whant to be able to edit username, just display his name.
This code I use in View:
<label>Username </label>
<div class="editor-field">
#Html.EditorFor(model => model.username)
</div>
So what to put instead EditorFor, that will display username (just for reading, not for editing).
Why not just use #Html.DisplayFor instead? This will just display the username as a label. Or, if you wish to use #Html.EditorFor or #Html.EditorForModel, you can create a custom editor template for your username property, and in the editor template, just display the content instead of enabling editing.
Also, I would recomment you exclude this property during model binding by using [Bind(Exclude="username")] with your model parameter in your POST action method, to protect from injection attacks. More about this here.
find solution:
#Html.TextBoxFor(model => model.username, new {disabled = "disabled", #readonly = "readonly" })

Same property in two different tabs (divs). Property is null when tab 2 is posted to action method

When I post back to the server when tab2 is active viewModel.FirstName is null in the action method. How do you tell the modelbinder that it should take #Html.EditorFor(m => m.FirstName) from tab2 when that tab is active? Everything works fine for tab1.
jQuery hide() and show() are used for switching between tabs.
Controller
[HttpPost]
public ActionResult Index(MyViewModel viewModel)
View
<div id="tab1">
#Html.EditorFor(m => m.FirstName)
</div>
<div id="tab2">
#Html.EditorFor(m => m.FirstName)
</div>
It sounds like you have both FirstName input fields inside the same form.
Something like:
<form>
<div id="tab1">
#Html.EditorFor(m => m.FirstName)
</div>
<div id="tab2">
#Html.EditorFor(m => m.FirstName)
</div>
</form>
When you post this, the form is submitted as:
FirstName=valueFromField01&FirstName=valueFromField02
From the behavior you are describing, it seems that once the model binder sets the FirstName field in your MyViewModel, it ignores the second one (but I'm not really sure about that).
Solutions:
Rather than have a form with different tabs inside of it, have a form inside each tab. This will ensure you only have one FirstName inside a form.
Update the model so that you get both fields. You would need to use an array of string: string[] FirstName.
Update:
Instead of updating your ViewModel, it might be easier to simply add another parameter to your action method so you can get both FirstName values and then figure out which one was actually provided:
public ActionResult Index(MyViewModel viewModel, string [] FirstName).
Then you can have logic in your action method to set the FirstName in your viewModel:
if(!string.IsNullOrEmpty(FirstName[0]))
{
viewModel.FirstName = FirstName[0]
}
else if(!string.IsNullOrEmpty(FirstName[1]))
{
viewModel.FirstName = FirstName[1];
}
You could achieve that disabling the duplicated name form elements. By default, disabled form elemnts will not be passed to the request, and your Controller problably will receive the name corectly from the tab2 when it is shown active.
So. here follows one example
$('#tab1')
.hide()
.find('input[name="FirstName]"')
.prop('disabled',true);
$('#tab2').show()
.find('input[name="FirstName]"')
.prop('disabled',false);
Latter I suggest you should wrap this behaviour inside a function.
Hope it helps.

Resources