How to prevent saving of duplicate data? - asp.net-mvc

I am developing MVC app.
I am using Jquery in Creat-Veiw for validate the data.
I am adding the Role and checking whether that Role(or you can say UserName) already exists in DB or not.
If Role already exists then validation message should display and should not be allow to add in db (should not allow to save).
I have a text-box which accepts the Role, on the blur function I have checked whether Role already exists or not.
Every thing working ok, If Role already exists then validation message comes up.
But after clicking on save button it saves in db.
I want to prevent it ? How to do this ?
I have below code of Create View.
#model IEnumerable<PaymentAdviceEntity.Role>
<div id="roleList">
<div class="span6">
<div class="span12 HeaderField2">
Roles
<legend style="margin-bottom:2px;margin-top:5px;"></legend>
</div>
<div class="span12">
<div style="display:inline-block"></div>
<div id="addrole" style="display:none">
<span> #Html.TextBox("RoleName", String.Empty, new { #id = "RoleName",style="margin-bottom:0px;" })</span>
<span>
<input type="button" value="Save" id="btnSave"/>
<input type="button" value="Cancel" id="btnCancel" />
</span>
</div>
<div style="margin-top:5px;">
<span id="RoleNameValidation" style="display:none;color:Red;">Role already exists</span>
</div>
</div>
</div>
For this I am using the below Jquery.
$("#RoleName").blur(function ()
{
var Role_Name = $('#RoleName').val();
//alert(RoleName);
var url = "#Html.Raw(Url.Action("checkForUniqueName","Role",new {#RName = "RoleName"}))";
url = url.replace("RoleName", Role_Name);
$.post(url, function (data)
{
if (data == false) {
$("#RoleNameValidation").show();
$('#RoleName').focus();
}
else {
$("#RoleNameValidation").hide()
}
});
});
and the controller Code is....
public ActionResult checkForUniqueName(string RName)
{
bool Valid = false;
var RoleList = from e in db.Roles
where e.Name.Equals(RName)
select e;
if (RoleList.Count() > 0 )
{
Valid = false;
}
else
{
Valid = true;
}
return Json(Valid, JsonRequestBehavior.AllowGet);
}

You can use validation for this purpose if you don't want to insert duplicate records in database.
Try to create a custom rule using the jQuery Validate plugin (using addMethod) that checks if the role is already exists in database.You can find good help at http://matthewmuro.com/2012/05/08/adding-custom-jquery-validation-to-your-form/

Related

Assign authority to a user without user input when updating user profile

I've created a form that a user updates to update his profile. When I update the details of the user, and I log out and log in again, I get access denied. I found out that the reason for this was with the authority, every time I updated the table, other details were saved, but the authority is lost and as a result, access is denied.
So I would like to assign the role again within the form but without the user having any input. Any advise on how to implement that is appreciated.
below is my gsp;
<div class="form-group">
<label class="col-sm-5 control-label">
Roles
</label>
<div class="col-sm-5 ">
<g:each in="${roles}" var="role" status="i">
<div class="checkbox-inline">
<g:checkBox name="roles" value="${role.id}"
checked="${role.authority == "ROLE_MEMBER" ? 'true': user.hasRole(role)}"/>
<label for="roles[${i}]">${role.authority}</label>
</div>
</g:each>
</div>
</div>
<div class="form-group">
<div class="${hasErrors(bean: user, field: 'natureOfIndividual', 'error')} required">
<label for="natureOfIndividual" class="col-sm-5 control-label">
<g:message code="user.natureOfIndividual.label" default="Nature of Individual"/>
</label>
<div class="col-sm-5">
<g:select name="natureOfIndividual"
from="${['Local', 'Foreign']}"
class="form-control" noSelection="['': '-----Select-----']"
value="${user?.natureOfIndividual}"/>
</div>
</div>
</div>
With this code am not able to see the checkboxes. Still finding out why. But ultimately, I don't want the user to see any checkboxes, I want to assign the authority without his/her input.
I got a solution. In my UserController.groovy, there was updateRoles method that was called in update method. I commented out the method call. And now the roles are not affected after an update. Below is the code;
#Transactional
def update(User user) {
if (user == null) {
transactionStatus.setRollbackOnly()
notFound()
return
}
if (user.hasErrors()) {
transactionStatus.setRollbackOnly()
respond user.errors, view: 'edit'
return
}
boolean passChange = false
if (user.isDirty('password')) {
passChange = true
}
user.save flush: true
//updateRoles(user)
request.withFormat {
form multipartForm {
if (passChange) {
flash.message = "A user with username '${params.username}' and password '${params.password}' has been Updated"
} else {
flash.message = "Your profile has been updated"
}
redirect user
}
'*' { respond user, [status: OK] }
}
}
private updateRoles(User user) {
UserRole.removeAll(user)
List roleIds = params.roles instanceof String ? [params.roles] : params.roles
roleIds?.each { roleId ->
def role = Role.get(roleId)
UserRole.create(user, role, true)
}
}
As you've seen, I have commented out the method call in the update method. So when users update their details, their authorization is still preserved.

Showing values from controller in view in asp.net mvc

I have a form, with different input fields, where user can enter their information.
Inside of the form, I have 2 buttons. When user clicks one button called 'Add address', I want to fill up a div with the address. And when user clicks other button called 'Preview', the form is validated and prepared for preview page.
Below is how 'My Adrress' button is defined in Index.cshtml
<button id ="address" class="btn btn-default" onclick="location.href='#Url.Action("populateAddress","Information")?addressID=2222'">
Add Address
</button>
So, when user clicks, Add Address, I want to fill up the address that I am retrieving from database in the div on Index.cshtml. Below is where I want to display the retrieved address:
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-3">
#Html.Label("Address", htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-6">
#ViewBag.FeedAddress //Here I want to display my retrieved address
</div>
</div>
So, on button click, I am calling my 'Information' controller method 'populateAddress' and passing the addressID parameter '2222' to it.
Below is how I am defining my 'populateAddress' method in my controller:
public void populateAddress(string addressID = null)
{
var addressDetail = db.Agency.Where(e => e.AddressCode == addressID).ToList();
string AddressRetrieved= "";
string StreetAddress, City, State, Zip = "";
foreach(var detail in addressDetail )
{
StreetAddress = detail.Address;
City = detail.City;
State = detail.State;
Zip = detail.Zip;
AddressRetrieved= StreetAddress + Environment.NewLine + City + ", " + State + " - " + Zip;
}
ViewBag.FeedAddress = AddressRetrieved
}
So, here, my ViewBag is getting filled with my retrieved address.
But, my issue is, after it gets filled with the address, instead of showing it on my Index.cshtml page in the div where I am retrieving back the value from ViewBag, my page is instead getting submitted and showing my validations.
I want that, once user fills up part of the form above 'Add Address' button and clicks 'Add Address' button, my address is retrieved from ViewBag, shown inside the div and user proceed filling up the rest of the form.
I am unable to get this kind of behavior.
Can anyone please help me to achieve that behavior or may be tell what I am missing. Thanks!
EDIT:
Please find Index.cshtml code. The page is long, so I am just adding required code:
// input fields for user
<div class="form-group">
<div class="col-md-2">
#Html.Label("Title", htmlAttributes: new { #class = "control-label" }) </div>
<div class="col-md-6">
#Html.EditorFor((e => e.Title), new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
//Add Address button
<button id ="address" class="btn btn-default" onclick="location.href='#Url.Action("populateAddress","Information")?addressID=2222'">
Add Address
</button>
//section to display retrieved address
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-3">
#Html.Label("Address", htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-6">
#ViewBag.FeedAddress //Here I want to display my retrieved address
</div>
</div>
// input fields for user
<div class="form-group">
<div class="col-md-2">
#Html.Label("Description", htmlAttributes: new { #class = "control-label" }) </div>
<div class="col-md-6">
#Html.EditorFor((e => e.Description), new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
//Preview Button
<div class="form-group">
<div class="col-md-offset-2 col-md-6">
<input type="submit" value="Preview" class="btn btn-default" />
</div>
</div>
In the controller (named mainController for this example):
public JsonResult GetAddress(int addressId)
{
// do whatever to get what you need
// the Address model will need to be JSON serialized
return JSON(Address);
}
In the javascript:
function GetAddress(addressId)
{
$.ajax({
type: "GET",
async: false,
url: "/main/GetAddress?addressId=" + addressId
contentType: "application/json",
context: this,
success: function (data) {
console.log(data);
// do stuff here
},
error: function (error) {
alert("error");
}
});
}
Important routing info:
The url is "/main/GetAddress/" which means it will route to the controller mainController (notice the 'main' part matches) and the function inside the controller is GetAddress. It is a "GET" request so using the url variable is fine.
This is the basic structure of how you do an ajax call with MVC.
Special note: In the controller method you return a JsonResult, NOT an ActionResult! Use ActionResult when you are trying to route through a View and have the Razor engine create the HTML markup. But if you are just returning JSON, use JsonResult.
EDIT:
In case you want to do a POST instead of a GET, here is what it would look like:
In the controller:
public JsonResult PostSomething(MyClass data)
{
// do something with the data -- class is MyClass
var result = ...... // whatever the result is, Null is ok I'd recommend some sort of "successful" reply
return JSON(result);
}
In the javascript:
function SubmitForm()
{
var formData;
// common to use jQuery to get data from form inputs
// use JSON.stringify to serialize the object
var data = JSON.stringify(formData);
// the ajax is almost the same, just add one data: field
$.ajax({
type: "POST",
url: "/main/PostSomething"
contentType: "application/json",
data: data, // the second 'data' is your local variable
success: function(data){
console.log(data);
},
error: function(error){
alert(error)
}
});
}
The 'asynch: false' and 'context: this' from the first example are actually not necessary in either (most of the time).
As with most of programming, there is more than one way to do it. These examples are just simple (but fairly standard) snippets to get you on the right track.

New value in HTML.DropDownListFor(...) not setting in Controller [Post] method?

Hopefully someone can see how to go about this, because I've tried everything I can think of. When the Create() View in my MVC5 application loads I first populate several [SelectList(...)]'s in my Controller (ex.):
ViewBag.Model_Id = new SelectList(db.DBT_MODELS.OrderBy(x => x.MODEL_DESCRIPTION), "MODEL_ID", "MODEL_DESCRIPTION");
I then on my Create() View use this [SelectList(...)] to Populate an Html.DropDownListFor(...):
<div class="form-group">
<span class="control-label col-md-2">Model:</span>
<div class="col-md-4">
#Html.DropDownListFor(model => model.MODEL_ID, (SelectList)ViewBag.Model_Id, htmlAttributes: new { #class = "form-control dropdown", #id = "selectModel" })
#Html.ValidationMessageFor(model => model.MODEL_ID, "", new { #class = "text-danger" })
</div>
<div class="col-md-2">
<div class="btn-group">
<button id="createNewModel" type="button" class="btn btn-success" aria-expanded="false">CREATE NEW</button>
</div>
</div>
<div class="col-md-4">
<div id="createModelFormContainer" style="display:none">
<form action="/createNewModel">
<input type="text" id="textNewModel" name="model_description" placeholder="New Model" />
<input type="button" id="submitNewModel" value="Submit" />
<input type="button" id="cancelNewModel" value="Cancel" />
</form>
</div>
</div>
</div>
Simple enough, and this all works as expected. The problem lies in a bit of extended functionality I've tried to incorporate. My main class has several of these properties which are basically Foreign Key's in my DB. When a User goes in to Create/Edit() an entity in my main Model, I wanted to allow them to be able to add new entities to these foreign tables without needing to navigate away from the current View.
As such, I added (for each foreign property, using (Model) as an example) the code shown above and again directly below with a button to Show/Hide a small form for users to insert a new value and have it added to the DropDownList:
<div class="col-md-2">
<div class="btn-group">
<button id="createNewModel" type="button" class="btn btn-success" aria-expanded="false">CREATE NEW</button>
</div>
</div>
<div class="col-md-4">
<div id="createModelFormContainer" style="display:none">
<form action="/createNewModel">
<input type="text" id="textNewModel" name="model_description" placeholder="New Model" />
<input type="button" id="submitNewModel" value="Submit" />
<input type="button" id="cancelNewModel" value="Cancel" />
</form>
</div>
</div>
My submitNewModel() click event below gets the user's inputted new value and then uses a JSON call to a Controller Method to add it in the Database Table. This new value (and new ID for it) are then returned, the form for the DropDownList is reset, and I set the DropDownList's current value as the newly added one:
$('#createNewModel').click(function () {
$('#createModelFormContainer').show();
})
$('#cancelNewModel').click(function () {
$('#createModelFormContainer').hide();
})
$('#submitNewModel').click(function () {
var form = $(this).closest('form');
var data = { description: document.getElementById('textNewModel').value };
$.ajax({
type: "POST",
dataType: "JSON",
url: '#Url.Action("createNewModel", "INV_ASSETS")',
data: data,
success: function (resp) {
if (resp.ModelExists)
{
alert("Model [" + resp.Text + "] already exists. Please select from the DropDown.");
} else {
$('#selectModel').append($('<option></option>').val(resp.MODEL_ID).text(resp.Text));
form[0].reset();
$('#createModelFormContainer').hide();
var count = $('#selectModel option').size();
$('#selectModel').prop('selectedIndex', count - 1);
$('#selectModel').val(resp.MODEL_ID);
//document.getElementById('selectModel').value = resp.MODEL_ID; - Shows dropdown as blank [ ] once executed.
}
},
error: function () {
alert("ERROR - Something went wrong adding new Model [" + resp.Text + "]!");
$('#createModelFormContainer').hide();
}
});
//reloadForNewEntity();
});
The createNewModel() method that is called in my Controller:
public JsonResult createNewModel(string description)
{
DBT_MODELS model = new DBT_MODELS()
{
// ID auto-set during save.
MODEL_DESCRIPTION = description.Trim(),
CREATED_DATE = DateTime.Now,
CREATED_BY = System.Environment.UserName
};
var duplicateModel = db.DBT_MODELS.FirstOrDefault(x => x.MODEL_DESCRIPTION.ToUpper() == model.MODEL_DESCRIPTION.ToUpper());
try
{
if (duplicateModel == null)
{
if (ModelState.IsValid)
{
db.DBT_MODELS.Add(model);
db.SaveChanges();
// Ensure the [model.ID] is properly set after having been saved to and auto-generated in the database.
model.MODEL_ID = db.DBT_MODELS.FirstOrDefault(x => x.MODEL_DESCRIPTION.ToUpper() == model.MODEL_DESCRIPTION.ToUpper()).MODEL_ID;
}
}
else
{
model = duplicateModel;
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
return Json(new { ID = model.MODEL_ID, Text = model.MODEL_DESCRIPTION, ModelExists = (duplicateModel != null) }, JsonRequestBehavior.AllowGet);
}
Visually speaking, everything works as intended up to this point. The problem is when I go to Save the main entity I am Creating/Editing.
Any value that was already in the Foreign Tables, and thus in the DropDownList when the View loads, saves just fine; but if I add a new Foreign Table value for these main entity properties (though visually added and the currently selected values for the individual DropDownLists) the [POST] method then executes with each foreign id value set as 0 (ex. MainClass.Model_ID = "0" vs expected MainClass.Model_ID = "625", MainClass.Type_ID = "0" vs expected MainClass.Type_ID = "17", MainClass.Location_ID = "0" vs expected MainClass.Location_ID = "82", etc.)
Basically if the value selected in the Html.DropDownListFor() is one of my newly added values, the POST controller method always renders the MainClass.*_ID value which the selected Html.DropDownListFor() value corresponds to as "0".
Can anyone point me to how to get this working? I have tried:
Changing how my JavaScript sets the value in the DropDownList after the the JSON call to my Controller Actions returns (ex): //document.getElementById('selectModel').value = resp.MODEL_ID; - Shows dropdown as blank [ ] once executed. vs $('#selectModel').val(resp.MODEL_ID); which visually renders the expected new value in the DropDownList.
On return from the Controller method, setting a new ViewBag variable and then hoping to reference the saved value in the POST method (did not work, the JavaScript rendered my #Viewbag.PostModelID = resp.ModelID as "= resp.ModelID" and threw many expected errors).
EDIT:
[Redacted for N/A]
EDIT2: Good to go. Thanks everyone for the suggestions!
The json data you are returning from your action method is in this format.
{
"ID": 24,
"Text": "IOS",
"ModelExists": false
}
But in your code, you are trying to access MODEL_ID property which does not exist in the resp object.
$('#selectModel').append($('<option></option>').val(resp.MODEL_ID).text(resp.Text));
Change your code to use ID property value
$('#selectModel').append($('<option></option>').val(resp.ID).text(resp.Text));
$('#selectModel').val(resp.ID);
In your controller where you create the new model.. your json object that you're returning is ID, Text, ModelExists, but in your javascript you're setting the val property of the new <option> to MODEL_ID.. these 2 need to match..
So change your javascript to be
.val(resp.ID)
or change the return value in your controller action to
return Json(new { MODEL_ID = model.MODEL_ID, Text = model.MODEL_DESCRIPTION
You're also referencing MODEL_ID here
$('#selectModel').val(resp.MODEL_ID);
so make sure if you don't change your controller action, you update this also

MVC Force jQuery validation on group of elements

My form I am designing with MVC 4 has mutiple DIVS with many elements in each one. My objective is to open/close DIVS as the user completes the fields. However, I want to use the unobtrusive validation on each DIV, rather than the whole form. Is that possible without checking each element individually? Maybe using a DIV ID or something? I don't want to build this massive function to check each and every element in each DIV just so the user can move to the next DIV.
I am trying this and it is not working:
var elems = [];
var valid = true;
("#Contact").find('.text_input').each(function() {
elems.push(this.id);
}
for (var i = 0; i<= elems.length; i++) {
if ($("#" + elems[i]) != undefined) {
$("#form1").validate().element("#" + elems[i]))
if ($("#" + elems[i]).valid()) {
}
else {
valid = false;
}
}
}
but I keep getting an undefined error. The elements in the DIV that have the class text_input are the ones with validation required.
You can validate individual controls using Validator.element(element) - see documentation here, so you could use the following approach (you haven't posted the views html so can't write the actual code for you)
In the Next button click event
Select all the the controls within the
associated div - e.g. var controls = $(this).closest('div').find('input, textarea, select');
In an $.each loop, call $("form").validate().element($(this));
If necessary, test if valid with $(this).valid();
If everything is valid, hide the current div and display the next
Edit (example added)
View
<div class="section">
<h2>Section 1</h2>
.... // Your inputs and validation
#Html.LabelFor(m => m.SomeProperty)
#Html.TextBoxFor(m => m.SomeProperty)
#Html.ValidationMessageFor(m => m.SomeProperty)
<div class="error"></div>
<button type="button" class="next">Next</button>
</div>
<div class="section">
<h2>Section 2</h2>
.... // Your inputs and validation
<div class="error"></div>
<button type="button" class="next">Next</button>
</div>
<div class="section">
<h2>Section 3</h2>
.... // Your inputs and validation
<div class="error"></div>
<button type="submit" class="next">Submit</button> // submit button for last section
</div>
CSS
.section:not(:first-of-type) {
display:none;
}
Script
$('button').click(function () {
var container = $(this).closest('.section');
var isValid = true;
$.each(container.find('input'), function () {
$('form').validate().element($(this));
if (!$(this).valid()) {
isValid = false;
return false;
}
});
if (isValid) {
container.next('.section').show().find('input').first().focus();
container.hide();
} else {
container.find('.error').text('please complete');
}
});

The model item passed into the dictionary is of type 'BlogHomePageModel', but this dictionary requires a model item of type 'BlogHomePageModel'

I'm using Umbraco 7.04. I would post code but I can't determine what is causing the problem. I did make some edits to a class in my App_Code folder and my website started displaying this error. I reverted those edits but still get the error.
A coworker mentioned that .net can cache files so I tried recycling app pool and editing web.config to no avail.
EDIT: here is the code I believe was causing the problem, although it seemed to have gone away randomly.
BlogHomePage View
#inherits Umbraco.Web.Mvc.UmbracoViewPage<BlogHomePageModel>
#{
Layout = "BlogLayout.cshtml";
var BlogBackgroundImageCss = Html.Raw(HttpUtility.HtmlDecode(Model.BannerImageBackgroundImageCss));
var BlogHomeContent = Html.Raw(HttpUtility.HtmlDecode(Model.BlogHomeContent));
var AllTags = Html.Raw(HttpUtility.HtmlDecode(thunder.TagHelper.GetAllTags(Model.Content)));
var PagingHtml = Html.Raw(HttpUtility.HtmlDecode(Model.PagingHtml));
}
<div class="blog-area">
<div class="blog-banner-area" style="#BlogBackgroundImageCss" >
<span>#Model.BannerImageTitle</span>
</div>
<div class="blog-nav-area">
<button class="blog-nav-collapse-button"><span>Search</span></button>
<div class="blog-nav-inner-area">
#{ Html.RenderPartial("BlogHomeSearchInformation", Model); }
#{ Html.RenderPartial("BlogPostSearch"); }
#AllTags
#{ Html.RenderPartial("BlogHomeAside", Model); /*use partial to render blog post aside*/ }
</div>
</div>
<div class="blog-main-area">
<div class="blog-heading-area">
<div class="blog-heading-text-container">
#BlogHomeContent
<button class="blog-about-this-blog-expand-button">Read More</button>
</div>
</div>
#if (Model.Posts.Count() > 0) {
foreach (var Post in Model.Posts) {
Html.RenderPartial("BlogHomePostPartial", Post); /*use partial to render blog post content*/
}
#PagingHtml
} else {
<p>Sorry, but no posts matched your query.</p>
}
</div>
</div>
BlogHomeSearchInformationPartial
#inherits Umbraco.Web.Mvc.UmbracoViewPage<BlogHomePageModel>
#{
string SearchTerm = (!string.IsNullOrEmpty(Request.QueryString["s"])) ? Request.QueryString["s"] : "";
string TagTerm = (!string.IsNullOrEmpty(Request.QueryString["t"])) ? Request.QueryString["t"] : "";
}
<div id="blog-search-results-information">
#if (!string.IsNullOrEmpty(SearchTerm)) {
if (Model.TotalResults == 1) {
<p>Your search for "#SearchTerm" returned #Model.TotalResults result. Click here to return to home page.</p>
} else {
<p>Your search for "#SearchTerm" returned #Model.TotalResults results. Click here to return to home page.</p>
}
}
#if (!string.IsNullOrEmpty(TagTerm)) {
if (Model.TotalResults == 1) {
<p>There is #Model.TotalResults post tagged "#TagTerm". Click here to return to home page.</p>
} else {
<p>There are #Model.TotalResults posts tagged "#TagTerm". Click here to return to home page.</p>
}
}
</div>
BlogPostSearch
#inherits UmbracoTemplatePage
#{
string SearchTerm = "";
SearchTerm = Request.QueryString["s"];
}
<form role="search" method="get" id="searchform" action="/">
<div class="blog-search-area">
<input type="search" name="s" value="#SearchTerm">
<button type="submit">Search</button>
</div>
</form>
BlogPostAside
#inherits Umbraco.Web.Mvc.UmbracoViewPage<BlogHomePageModel>
#{
var AsideLinks = Html.Raw(HttpUtility.HtmlDecode(Model.AsideLinks));
}
#if (!string.IsNullOrEmpty(Model.AsideHeading) || !string.IsNullOrEmpty(Model.AsideSubheading) || !string.IsNullOrEmpty(Model.AsideContent) || !string.IsNullOrEmpty(Model.AsideLinks)) {
<div class="blog-contact-area">
<span class="blog-contact-heading">#Model.AsideHeading</span>
<span class="blog-contact-subheading">#Model.AsideSubheading</span>
<p>#Model.AsideContent</p>
#AsideLinks
</div>
}
Seems to me you have defined a special model on your view (or you did inherit form something).
Try to remove the #model and the #inherits from your view.
problem solved itself mysteriously :( After a little more research I believe it may be related to this question: The model item passed into the dictionary is of type ‘mvc.Models.ModelA’ but this dictionary requires a model item of type ‘mvc.Models.ModelB‘

Resources