How to send enquiry form details to email in mvc - asp.net-mvc

Please any one help me out to design enquiry form that having Name,Mobile No,Query and Address attributes and all these attributes should be sended to my email when visitor clicked send button after fill same details.
Need code for MVC..

First you need to create a model something like this:
public class Inquiry
{
public string Name { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
public DateTime Date { get; set; }
public string Message { get; set; }
}
Then you need in your controller when returning your view to pass in a new model:
[HttpGet]
public IActionResult Contact()
{
return View(new Inquiry());
}
Then create your form in HTML
Then in your controller have:
[HttpPost]
public IActionResult Contact(Inquiry inquiry)
{
{new Email().Send(inquiry); //Using your email class
return View(<Thank you page or whatever>);
}
Don't forget validations etc...

Related

Model binding Asp net core 2.2

I have the following complex model:
public class User
{
public int Id { get; set; }
public string UserName { get; set; }
public int UserId { get; set; }
}
I need to bind the whole model in my action method using [FromBody], while Id property should come [FromQuery]. My action method looks like this:
public IActionResult Delete([FromBody]User userRequest)
{
// Some code
}
The thing is that I can't change the model, because it is 3-rd party and also, I can't have Id as the second parameter in action method, because I have validation logic for userRequest where I need the Id. Any ideas?
Use a DTO/view model and map over to User. For example:
public class UserDTO
{
public string UserName { get; set; }
public int UserId { get; set; }
}
Then:
public IActionResult Delete(int id, [FromBody]UserDTO userRequest)
{
var user = new User
{
Id = id,
UserName = userRequest.UserName,
UserId = userRequest.UserId
}
// do something
}

MVC parameter not binding to controller action (KENDO UI)

Hope someone can help - this has been bugging me for around 2 hours - its probably something simple :)
Kendo UI Grid sends a request to my controller
http://localhost:1418/user/update?UserID=1&UserName=Admin&RoleName=Admin&Email=c.j.hannon%40gmail.com&Active=true&Company%5BCompanyID%5D=1&Company%5BCompanyName%5D=asd
However, the controller class 'Company' isnt bound by the binder? Can any one help my view model and controller action signature are below:
[HttpGet]
public JsonResult Update(UserViewModel model)
{
svcUser.UpdateUser(new UpdateUserRequest() {
UserID=model.UserID,
RoleID = model.RoleName,
Email = model.Email,
Active = model.Active.GetValueOrDefault(false),
UserName = model.UserName
});
return Json("", JsonRequestBehavior.AllowGet);
}
public class UserViewModel
{
public int UserID { get; set; }
public string UserName { get; set; }
public string RoleName { get; set; }
public string Email { get; set; }
public bool? Active { get; set; }
public CompanyViewModel Company { get; set; }
}
Cheers
Craig
A few things. Your immediate problem is that Company is mapped to a complex object not a primitive type. Kendo Grid just does not do this (as of this writing). Just guessing, but you probably want to setup a foreign key binding on the Grid and just pass back the Id of the company from a listbox. This is not as bad as you think and it will immediatly fix your problem and look nice too.
Maybe personal taste but seems to be a convention. Use the suffix ViewModel for the model that is bound to your View and just the suffix Model for your business objects. So a Kendo Grid is always populated with a Model.
Ex.:
public class UserModel
{
public int UserID { get; set; }
public string UserName { get; set; }
public string RoleName { get; set; }
public string Email { get; set; }
public bool? Active { get; set; }
public int CompanyID { get; set; }
}
public class CompanyModel
{
public int ID { get; set; }
public string Name { get; set; }
}
public class UserViewModel
{
public UserModel UserModel { get; set; }
public IList<CompanyModel> Companies { get; set; }
}
public ActionResult UserEdit(string id)
{
var model = new UserViewModel();
model.UserModel = load...
model.Companies = load list...
return View(model);
}
#model UserViewModel
...
column.ForeignKey(fk => fk.CompanyId, Model.Companies, "ID", "Name")
(Razor Notation)
BUT! This is just an example, you are better off Ajax loading the Grid with the IList becuase I assume you have many Users in the Grid at once, though you could server bind off the ViewModel with a List too. But the list of Companies is probably the same every time, so map it to the View just liek this rather than Ajax load it every time you do a row edit. (not always true)

MVC create using derived class

I'm new to MVC, so I apologize in advance if something doesn't make sense.
I have a base class (let's say "Person"), and 2 derived classes ("Student", "Professor").
I want to use 1 view for the Create functionality, with Partial views that contain the creation forms for either a student or professor. If I add a parameter, I can check against that to determine which partial view to show.
But my question is this: When the "Create" button is clicked, how can I determine which object is being created?
Edit (please bear w/ me, as I just created these to illustrate the problem)
Person class:
public class Person
{
public string Gender { get; set; }
public int ID { get; set; }
}
Student class:
public class Student : Person
{
public string LastName { get; set; }
public string FirstName { get; set; }
public List<Course> Courses { get; set; }
}
Professor class:
public class Professor : Person
{
public string LastName { get; set; }
public string FirstName { get; set; }
public double AnnualSalary { get; set; }
}
So then my Create controller looks like this:
public ActionResult Create(int personType) //1=student, 2=professor
{
var x = new {
Student = new Student(),
Professor = new Professor()
};
ViewBag.PersonType = personType;
return View(x);
}
Then my view looks like this:
<div>
#if (ViewBag.PersonType == 1)
{
#Html.Partial("CreateStudentPartialView", Model.Student)
}
else
{
#Html.Partial("CreateProfessorPartialView", Model.Professor)
}
So, the question is what would the associated create action look like, when the "Create" button is clicked in either partial view?
[HttpPost()]
public ActionResult Create(....) //What would I put as parameter(s)?
{
//no idea what to do here, since I don't know what object is being passed in
return RedirectToAction("Index");
}
Your best bet here is to have multiple POST actions in your controller.
So in the forms in your partial views, specify the action to hit
#using (Html.BeginForm("CreateStudent", "Create")) {
and
#using (Html.BeginForm("CreateProfessor", "Create")) {
Then your controller will look something like this:
[HttpPost]
public ActionResult CreateStudent(Student student)
{
//access the properties with the dot operator on the student object
//process the data
return RedirectToAction("Index");
}
and
[HttpPost]
public ActionResult CreateProfessor(Professor professor)
{
//access the properties with the dot operator on the professor object
//process the data
return RedirectToAction("Index");
}

asp.net mvc3 Bind Exclude on properties does not work

I have a class, which has 8 properties / 8 columns in DB. In the Edit page, I want to exclude the AddedDate and UserID fields. When a user edits a voucher, he can't overwrite the AddedDate or UserID values in the DB.
public class Voucher
{
public int ID { get; set; }
public string Title { get; set; }
public string SiteName { get; set; }
public string DealURL { get; set; }
public DateTime AddedDate { get; set; }
public DateTime? ExpirationDate { get; set; }
public string VoucherFileURL { get; set; }
public Guid UserID { get; set; }
}
Here is what I have for Edit controller:
// POST: /Voucher/Edit/5
[HttpPost]
public ActionResult Edit([Bind(Exclude = "AddedDate")]Voucher voucher)
{
if (ModelState.IsValid)
{
db.Entry(voucher).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(voucher);
}
On Edit page, when I click on submit, I got the following error:
System.Data.SqlServerCe.SqlCeException: An overflow occurred while converting to datetime.
Seems like the AddedDate didn't get excluded from the voucher object and triggered the error.
Would you please let me know how to fix it? Thanks!
(it is an updated version of asp.net mvc3 UpdateModel exclude properties is not working, I will go with another approach)
Never use your domain entities as action arguments and never pass your domain entities to your views. I would recommend you to use view models. In the view model you will include only the properties that you want to be bound from the view. The view model is a class that's specifically tailored to the requirements of a given view.
public class VoucherViewModel
{
public int ID { get; set; }
public string Title { get; set; }
public string SiteName { get; set; }
public string DealURL { get; set; }
public DateTime? ExpirationDate { get; set; }
public string VoucherFileURL { get; set; }
}
and then:
[HttpPost]
public ActionResult Edit(VoucherViewModel model)
{
// TODO: if the view model is valid map it to a model
// and pass the model to your DAL
// To ease the mapping between your models and view models
// you could use a tool such as AutoMapper: http://automapper.org/
...
}
UPDATE:
In the comments section #Rick.Anderson-at-Microsoft.com points out that while I have answered your question I haven't explained where the problem comes from.
The thing is that DateTime is a value type meaning it will always have a value. The [Bind(Exclude = "AddedDate")] works perfectly fine and it does what it is supposed to do => it doesn't bind the AddedDate property from the request. As a consequence the property will have its default value which for a DateTime field is 1/1/0001 12:00:00 AM and when he attempts to save this in SQL Server it blows because SQL Server doesn't support such format.

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