1

I have a page I am writing to send emails to customers. One of the ways to select customers to email is to select products they have. Each product has different detail information and you will also be able to choose specifics about the product to narrow down who you are emailing.

Because this is going to be complex I need to do the processing to come up with the customer email list on the controller side but it would be a nightmare to try to pull all the data form the controls to send to it manually.

I would like to use an AJAX call that on the controller side would get the model tied to the view, query the database, and send back the list of emails so on the view I can pop up outlook for them with the list of email addresses already populated. Because I need to go back to the view with data I don't think I can do this with a form post which is how I normally get model into into the controller.

Does someone know how I could accomplish this?

Here are some of the clases I have to try to help people understand my layout

public class ProductType
{
    [HiddenInput(DisplayValue = false)]
    public int ID { get; set; }

    [Required(ErrorMessage = "Please enter a product type description")]
    public string Description { get; set; }

    public virtual ICollection<ProductTypeDetail> ProductDetails { get; set; }
}

public class ProductTypeDetail
{
    [HiddenInput(DisplayValue = false)]
    public int ID { get; set; }

    [HiddenInput(DisplayValue = false)]
    public int? ProductTypeID { get; set; }

    public ProductType ProductType { get; set; }

    [Required(ErrorMessage = "Please enter a description")]
    public string Description { get; set; }

    [Required(ErrorMessage = "Please enter a valid type")]
    public string Type { get; set; }

    public virtual ICollection<ProductTypeDetailValidValue> ValidValues { get; set; }
}

The above 2 classes are for product types which someone could enter anything for and as many as they want. The product details are detail information you might need to know about your products. For example you could have a product type of Vehicle Registration System and put a product detail item in that for a specific import process that pertains to the product they you need to know if they use or not.

public Customer()
    {
        SiteVisits = new List<SiteVisit>();
        Payments = new List<Payment>();
        Contacts = new List<CustomerEmail>();
    }

    [HiddenInput(DisplayValue = false)]
    public int ID { get; set; }

    [Display(Name = "Name")] 
    [Required(ErrorMessage = "Please enter a customer name")]
    public string CustomerName { get; set; }

    [Display(Name = "Line 1")] 
    public string Address1 { get; set; }
    [Display(Name = "Line 2")] 
    public string Address2 { get; set; }
    [Display(Name = "Line 3")] 
    public string Address3 { get; set; }
    [Display(Name = "Line 4")] 
    public string Address4 { get; set; }

    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }


    [HiddenInput(DisplayValue = false)]
    [Required(ErrorMessage = "Please enter a customer type")]
    public int CustomerTypeID { get; set; }

    [Display(Name = "Type")] 
    public virtual CustomerType CustomerType { get; set; }

    [HiddenInput(DisplayValue = false)]
    [Required(ErrorMessage = "Please enter a customer status")]
    public int CustomerStatusID { get; set; }

    [Display(Name = "Status")]
    public virtual CustomerStatus CustomerStatus { get; set; }

    [DataType(DataType.MultilineText)]
    public string Comments { get; set; }

    [Required(ErrorMessage = "Please enter an expiration year")]
    public long ExpirationYear { get; set; }
    [Required(ErrorMessage = "Please enter an expiration month")]
    public long ExpirationMonth { get; set; }

    [Required(ErrorMessage = "Please enter a control name")]
    public string ControlName { get; set; }

    public Boolean Networked { get; set; }
    public long Population { get; set; }

    [Display(Name = "First Fiscal Month")] 
    public long FirstMonth { get; set; }

    [Display(Name = "FTP User Name")]
    public string FTPUserName { get; set; }

    [Display(Name = "FTP Password")]
    public string FTPPassword { get; set; }

    [Display(Name = "Customer ID")]
    public string CustomerUpdateID { get; set; }

    [DataType(DataType.Date)]
    [Display(Name = "Customer Since")] 
    public DateTime? StartDate { get; set; }

    public virtual ICollection<CustomerPhoneNumber> PhoneNumbers { get; set; }
    public virtual ICollection<CustomerProduct> Products { get; set; }
    public virtual ICollection<CustomerEmail> Contacts { get; set; }
    public virtual ICollection<SiteVisit> SiteVisits { get; set; }
    public virtual ICollection<Payment> Payments { get; set; }
}

public class CustomerProduct
{
    [HiddenInput(DisplayValue = false)]
    public int ID { get; set; }

    [HiddenInput(DisplayValue = false)]
    public int? ProductTypeID { get; set; }

    public virtual ProductType ProductType { get; set; }

    [HiddenInput(DisplayValue = false)]
    public int CustomerID { get; set; }

    public virtual Customer Customer { get; set; }

    [HiddenInput(DisplayValue = false)]
    public int? VersionID { get; set; }

    public virtual ProductVersion Version { get; set; }

    [HiddenInput(DisplayValue = false)]
    public int? StatusID { get; set; }

    public virtual ProductStatus Status { get; set; }

    public virtual ICollection<CustomerProductDetail> ProductDetails { get; set; }


}

 public class CustomerProductDetail
{
    [HiddenInput(DisplayValue = false)]
    public int ID { get; set; }

    [HiddenInput(DisplayValue = false)]
    public int CustomerProductID { get; set; }

    public virtual CustomerProduct CustomerProduct { get; set; }

    [HiddenInput(DisplayValue = false)]
    public int ProductTypeDetailID { get; set; }

    public virtual ProductTypeDetail ProductTypeDetail { get; set; }

    //[Required(ErrorMessage = "Please enter a value")]
    public string Value { get; set; }


}

So above I have the customer class. Each customer can be set up with any number of the product types you have set up and you can select values for the product details of that product type for this particular customer. The customers also contain contacts. that is the class that has the email addresses.

So I need to show a screen that displays all the product types you have set up and lets you select values for detail items on products you select then I need to query and find customers that match this

Dave Wade
  • 443
  • 1
  • 4
  • 18
  • I guess if worse comes to worse I can always do form post come up with the email addresses then use that data for a different vie where I pop up outlook but there is not really a need from the users point of view for another view so I would rather if it is possible just do ti all from the 1 view – Dave Wade Jan 11 '13 at 17:25
  • I don't understand the question. Why would it be a nightmare to pull all the data from the controls (view) to send manually? Would it make the signature of the action method too complicated or is it because actually iterating and getting all teh form data would be a nightmare? If the latter See http://stackoverflow.com/questions/1960240/jquery-ajax-submit-form and see http://api.jquery.com/category/forms/ namely the `serialize` method, which can then be used to serialize the values into an ajax submit. – Eli Gassert Jan 11 '13 at 17:28
  • That is kinda cool but it does not help me out in my situation. I have my program set up so that products and product details are a dynamic thing that you can add in and the site handles it. If i do a serialize to do email I am basically going to have to code to handle all the products and details so it defeats the purpose of them being able to dynamically alter them. that is why I wanted to get the model because then I have my array of products and details that they set up dynamically and I do not need to know anything about them to query the databsase – Dave Wade Jan 11 '13 at 18:17
  • I guess I don't understand the situation you're in, apologies. – Eli Gassert Jan 11 '13 at 18:21
  • I have added in the classes I use and a little more of a description to try to help people understand what I am trying to deal with. – Dave Wade Jan 11 '13 at 18:36
  • So can't you use a simple ViewModel to accomplish this? You can do a simple Composite VM, such as `public class SearchBy { public int DetailItemID { get; set; } public int ProductID { get; set; } }` and whichever of the two (mutually exclusive?) is in the search VM passed into the controller, that's what you use to search. It would then return results of type `Contact`. Am I getting warmer with what you're asking? – Eli Gassert Jan 11 '13 at 18:50

1 Answers1

1

All I needed to do was serialize the form and pass it as data in my ajax call. If on the Controller side that is getting called I have an argument that is of the same type as the model my view is strongly typed to the model binder is smart enough to fill in my object automatically

Dave Wade
  • 443
  • 1
  • 4
  • 18