MVC.net Hiding Fields within a model - asp.net-mvc

So I am creating a an API with ASP.net MVC Web API. I currently have a model which contains the fields for a user in the database. I have a password field on this model. See below for an example.
public class Account
{
[Key]
public Guid UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
I return this model using JSON when a controller method is called over HTTP. This works fine.
My question is, how do I stop the password field being returned alongside with it? Without removing the field altogether.
My initial idea is to create another model class which I use to return the data without the password field, but I'd rather not repeat myself for the sake of one field.
Any suggestions?

You should be able to mark these fields with
[JsonIgnore]
[XmlIgnore]
public string Password { get; set; }
Preventing these fields to be used in either JSON or XML requests.

Related

how to validate Viewmodel in multiLang in mvc

I have this viewModel and I use Asp.net MVC and EF code First .
public class AddNewsVM
{
public string Title { get; set; }
public string TitleEn { get; set; }
public string Body { get; set; }
public string BodyEn { get; set; }
public string Author { get; set; }
public bool IsActive { get; set; }
public Guid ImageId { get; set; }
}
But user can Add EnNews(englisg) Or FaNews(persian) or both of them . I don't Add Required to all them . how can I validatie it . for example I want if use enter En News Title user should enter All En Field . do I use If statement in Action ?
It depends on your needs. If you need both (client / server) validations, I recommend to use:
https://github.com/JeremySkinner/FluentValidation
If you want to just validate your ViewModel on server side (class level validation), you can write your own custom validation rules using the IValidatable.
http://weblogs.asp.net/scottgu/class-level-model-validation-with-ef-code-first-and-asp-net-mvc-3
You can do client side validation like this
create one javascript validation metod.
perform all your custom validation, if validation fails return false at the end return true.
call the validation method on submit button "onclick" event
eg:- onclick="return myValidationFunction()"

Entity Framework - How to prevent a model property from column creation?

Folks,
I am developing an web application based on ASP .NET MVC 4.
Let's say I define a model such as:
public class MyUser {
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
The database initializer code will automatically create a table with three columns - UserName, FirstName, and LastName.
However, let's say I don't want LastName to be part of the database table.
Is there any data annotation attribute that I can use to prevent a property from being exposed as a column?
Thank you in advance for your help.
Regards,
Peter
use NotMapped attribute. Here is a very good reference about different attribute you can use.
public class MyUser {
public string UserName { get; set; }
public string FirstName { get; set; }
[NotMapped]
public string LastName { get; set; }
}

Validation occurred client side with breeze entities for some properties which will be filled server side in the BeforeSaveEntity

I use the Durandal template in my asp.net mvc solution. The question here is related to Breeze which is also used in Durandal. Let's say I have the following entity in my model:
public class Driver
{
[Key]
public int Id { get; set; }
[Required]
public string Firstname { get; set; }
[Required]
public string Lastname { get; set; }
public string Comment { get; set; }
public int? CreatedById { get; set; }
public DateTime? CreatedTime { get; set; }
public int? UpdatedById { get; set; }
public DateTime? UpdatedTime { get; set; }
public virtual User CreatedBy { get; set; }
public virtual User UpdatedBy { get; set; }
}
As you can see, I have some properties used to track creation/updates for time and userid (UpdatedById, UpdatedTime, ...). I would like to let the user edit/create my drivers in some data entry pages then fill in these properties (UpdatedById, UpdatedTime, ...) server side automatically in the BeforeSaveEntity method.
It works but as you noted I had to allow nullable on the properties like int? or DateTime? because in case of adding a new entity (everything is blank) the validation failed if I didn't proceed like that.
My question: is there another solution or something that could be done to avoid using nullable types on my model (int? - DateTime?) for these properties which track my creation/edition?
Thanks.
Make them nonnullable and fill in "dummy" values of the client, in a "registered" ctor for each type that will then get overwritten on the server.

Using a model for multiple purposes

I'm new to ASP.NET MVC using Entity Framework and I'm trying to create a simple login system. At the moment I have UserProfile model that I wish to model a login form off of.
UserProfile.cs
namespace MyProject.Areas.Admin.Models
{
public class UserProfile {
[Key]
public int UserID { get; set; }
[Required]
[Display(Name = "Username")]
public string Username { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
public string EmailAddress { get; set; }
public string Telephone { get; set; }
}
}
As my login form will only require a username and password, is it correct for me to create a separate model (for instance, a LoginModel with just those properties, or should I contine to use the UserProfile model?
It feels better for me to create a separate model to model the login submission, but then I run into the issues such as making them reference the same table?
Thanks
You should have only one Model (Domain model), but different ViewModel class.
The ViewModel will only have the properties (from the Model) needed for a certain View /Action.
To manage mapping between Model and ViewModel(s), you should look at Mapping solutions (like AutoMapper, ValueInjecter...)
It looks you should distinguish view model and domain model. Interestin discussion was here.

ASP MVC 3.0 Complex View

I am developing a application for Sales Order Management using ASP.NET MVC 3.0. I need to develop a page where Customer Details can be added.
Customer Details Include
public class Customer
{
public int ID { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public string Alias { get; set; }
public int DefaultCreditPeriod { get; set; }
public Accounts Accounts { get; set; }
public IList<Address> Addresses { get; set; }
public IList<Contact> Contacts { get; set; }
}
public class Accounts
{
public int ID { get; set; }
public string VATNo { get; set; }
public string CSTNo { get; set; }
public string PANNo { get; set; }
public string TANNo { get; set; }
public string ECCNo { get; set; }
public string ExciseNo { get; set; }
public string ServiceTaxNo { get; set; }
public bool IsServiceTaxApplicable { get; set; }
public bool IsTDSDeductable { get; set; }
public bool IsTCSApplicable { get; set; }
}
public class Address
{
public int ID { get; set; }
public AddressType Type { get; set; }
public string Line1 { get; set; }
public string Line2 { get; set; }
public string Line3 { get; set; }
public string Line4 { get; set; }
public string Country { get; set; }
public string PostCode { get; set; }
}
public class Contact
{
public int ID { get; set; }
public ContactType Type { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public string PhoneNumber { get; set; }
public string Extension { get; set; }
public string MobileNumber { get; set; }
public string EmailId { get; set; }
public string FaxNumber { get; set; }
public string Website { get; set; }
}
Customer Requires a single page to fill all the customer details(General info, Account Info,Address Info and Contact Info). There will be multiple Addresses(Billing, Shipping, etc) and multiple Contacts (Sales, Purchase). I am new to MVC. How to Create the View for the above and Add multiple Address dynamically?
I often create wrapper models to handle this kind of situation e.g.
public class CustomerWrapperModel
{
public Customer Customer { get; set;}
public Accounts Accounts { get; set;}
public List<Address> AddressList { get; set}
//Add
public CustomerWrapperModel()
{
}
//Add/Edit
public CustomerWrapperModel(Customer customer, Accounts accounts, List<Address> addressList)
{
this.Customer = customer;
this.Accounts = accounts;
this.AddressList = addressList;
}
}
then declare the View to be of type CustomerWrapperModel and use editors like so:
#model MyNamespace.CustomerWrapperModel
#Html.EditorFor(model => model.Customer)
#Html.EditorFor(model => model.Accounts)
#Html.EditorFor(model => model.AddressList)
and have a controller to receive the post that looks like this:
[HttpPost]
public ActionResult(Customer customer, Accounts accounts, List<Address> addressList)
{
//Handle db stuff here
}
As far as adding addresses dynamically I found the best way to do this if you're using MVC validation and want to keep the list structured correctly with the right list indexes so that you can have the List parameter in your controller is to post the current Addresses to a helper controller like this:
[HttpPost]
public PartialResult AddAddress(List<Address> addressList)
{
addressList.Add(new Address);
return PartialView(addressList);
}
then have a partial view that just renders out the address fields again:
#model List<MyNamespace.Address>
#{
//Hack to get validation on form fields
ViewContext.FormContext = new FormContext();
}
#Html.EditorForModel()
make sure you address fields are all in one container and then you can just overwrite the existing ones with the returned data and your new address fields will be appended at the bottom. Once you have updated your container you can do something like this to rewire the validation:
var data = $("form").serialize();
$.post("/Customer/AddAddress", data, function (data) {
$("#address-container").html(data);
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");
});
NB. I know some people with have an issue with doing it this way as it requires a server side hit to add fields to a page that could easily just be added client side (I always used to do it all client side but tried it once with this method and have never gone back). The reason I do it this way is because it's the easiest way to keep the indexes on the list items correct especially if you have inserts as well as add and your objects have a lot of properties. Also, by using the partial view to render the data you can ensure that the validation is generated on the new fields for you out of the box instead of having to hand carve the validation for the newly added client side fields. The trade off is in most cases a minor amount of data being transferred during the ajax request.
You may also choose to be more refined with the fields you send to the AddAddress controller, as you can see I just post the entire form to the controller and ignore everything but the Address fields, I am using fast servers and the additional (minor) overhead of the unwanted form fields is negligible compared to the time I could waste coding this type of functionality in a more bandwidth efficient manner.
You pass your root model object to the View call in your controller like this:
public ActionResult Index() {
var customer = GetCustomer(); // returns a Customer
return View(customer);
}
And then your view looks something like this:
#model Customer
<!DOCTYPE html>
<!-- etc., etc. -->
<h1>Customer #Model.Name</h1>
<ul>
#foreach (var address in Model.Addresses) {
<li>#address.Line1</li>
}
</ul>
One gets the picture.
The code above depends on the #model directive, which is new in ASP.NET MVC 3 (see this blog post).
Is a good question :D for normal navigation properties such as Accounts doing this is not to hard:
#Html.EditorFor(model => model.Accounts.ID)
#Html.EditorFor(model => model.Accounts.VATNo)
will do something you want. But for collection navigation properties (Addresses and Contacts) you can't do this in one place by default. I suggest you use a different page for Addresses (and one for Contacts). Because it is the easiest way. But if you want to do this in one place (and also with out AJAX requests), you can create view by Customer, use scaffolding for model and it's simple navigation properties, and for lists (Addresses, Contacts) you must add them with JavaScript to the input fields (for example for each Address added, put it in an Array) and post fields to server. At server you can get main model and simple properties by default model-binder and for lists, you can 1) create your own model binder 2) parse them from inputted strings by yourself. Good lock

Resources