5

I have such table in a view

<table class='sendemailtable'>                
@if (!string.IsNullOrEmpty(Model.CustomerName))
{
<tr>
   <td style="font-size: 26px;">
   @Html.Label(string.Empty, Model.CustomerName)
   </td>
</tr>
}                   

<tr><td style="padding-top: 15px;">To:</td></tr>
<tr>
   <td>
   @Html.TextBoxFor(m => m.EmailTo)
   @Html.ValidationMessageFor(m => m.EmailTo);
   </td>
</tr>

<tr><td style="padding-top: 15px;">Subject:</td></tr>
<tr>
<td style="font-size: 22px;">
@Html.TextBoxFor(m => m.EmailBody)
</td>
</tr>

few more

<button style="..." type="submit">SEND</button>

</table>

These are not all items from model, it has some more ids which are not present in ui, have some property with only getter

    public int OfferID;
    public int SomeOfferID;
    public int CustomerID;

    #region Email

    [Required]
    [DataType(DataType.EmailAddress)]
    [RegularExpression(@"[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}", ErrorMessage = "Incorrect email")]
    public string EmailTo;

    private string emailBodyDefault;
    public string EmailBody
    {
        get
        {
            if (string.IsNullOrEmpty(emailBodyDefault))
                emailBodyDefault = string.Format("Hi,{1}please take a look. Offer ID: {0}{1}{1}Thanks", SomeOfferID, Environment.NewLine);

            return emailBodyDefault;
        }

        set { emailBodyDefault = value; }
    }

    private string emailSubject;
    [Required]
    public string EmailSubject
    {
        get
        {
            if (string.IsNullOrEmpty(emailSubject))
                emailSubject = string.Format("Offer ID: {0}", SomeOfferID);

            return emailSubject;
        }

        set { emailSubject = value; }
    }

    #endregion

I want to pass full my model to controller, to be able to send email from controller's action. Also need to validate user's email, and non-empty subject when user clicks send. How can i do this ?

Alexander
  • 431
  • 2
  • 5
  • 19

5 Answers5

5

If you want the complete model to be submitted, then you need to include all the model properties in your form. You can do this using @Html.HiddenFor(m => m.YourPropertyName) if you don't want them to be displayed. I don't see any form tags in your code, but I assume there are some?

You already have validation on your model properties as you've used the [Required] DataAnnotations, so to check this on the server side, you need to check ModelState.Valid when you post the data to your controller.

public ActionResult SubmitMyForm(MyModel model)
        {
            if (ModelState.IsValid)
            {
...

Response to comment:

the form would look something like this:

@using (Html.BeginForm())
{
    <table>
    ...
    </table>
}

The error is occurring because inside the using block, you don't need to prefix C# code with @. See this answer for an explanation.

Community
  • 1
  • 1
markpsmith
  • 4,860
  • 2
  • 33
  • 62
  • Thank you. Can you show where to put Html.BeginForm there? For example because if i put it before @if (!string.IsNullOrEmpty(Model.CustomerName)) VS (or resharper) says i dont need @ inside, but without @ i have an exception in runtime. I dont want my ui layout to be broken. – Alexander Jan 30 '14 at 11:03
  • +3 You just saved me so much time. I have been a little lost on how to actually get my values to my `[HTTPPOST]` Method ... now it is working. – Nick Sep 25 '15 at 13:12
3

These are not all items from model, it has some more ids which are not present in ui, have some property with only getter

For properties with only GETTERS -

Properties with only getters, even though if they are not part of the view, still they persist their values on from POST.

For example, if you have your model -

public class MyModel1
{
    public string name { get { return "Rami"; } }
    public string email { get; set; }
}

And your controller Actions -

public ActionResult Index()
{
    MyModel1 m = new MyModel1();
    m.email = "ramilu";
    return View(m);
}

public ActionResult submit(MyModel1 m)
{
    return null;
}

Finally your view -

@using (Html.BeginForm("submit", "New", FormMethod.Post))
{
    @Html.LabelFor(model => model.email, new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.email)
    @Html.ValidationMessageFor(model => model.email)
    <input type="submit" value="Create" class="btn btn-default" />
}

And when you hit submit button, even though you do not have name property in view, it will still be holding its value.

enter image description here

For properties with GETTERS and SETTERS -

These properties must be included in the form as hidden fields (or probably through some other way by using cookies or session or cache etc on server). Otherwise they will not persist their values.

For example -

public class MyModel1
{
    public string name { get; set; }
    public string email { get; set; }
}

Controller Actions -

public ActionResult Index()
{
    MyModel1 m = new MyModel1();
    m.email = "ramilu";
    m.email = "email";
    return View(m);
}

public ActionResult submit(MyModel1 m)
{
    return null;
}

Index View -

@using (Html.BeginForm("submit", "New", FormMethod.Post))
{
    @Html.LabelFor(model => model.email, new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.email)
    @Html.ValidationMessageFor(model => model.email)
    @Html.HiddenFor(model => model.name);
    <input type="submit" value="Create" class="btn btn-default" />
}

And when you hit the submit button, you will get all properties values. Here I used hidden fields -

enter image description here

Also need to validate user's email, and non-empty subject when user clicks send. How can i do this ?

You can use JQuery Unobstructive Validation with Model Data Annotations.

And simple Model Validation in ASP.Net MVC (server side)

ramiramilu
  • 17,044
  • 6
  • 49
  • 66
2

usually, i'm using TempData[] ..

in View :

<script>
$('form').submit(function() {
@{ TempData["FullModel"] = Model; }
});
</script>

in Controller:

[HttpPost]
public void Controller()
{
    YourModel model = (YourModel) TempData["FullModel"];
}
umon
  • 245
  • 2
  • 4
  • 11
0

You can use strongly typed view and a few steps to do this

    /// Use Strongly typed view (Type @Model yourModel)
    /// Use @HTML.BeginForm and a button with type="Submit"

    [HttpPost]
    public void Controller(YourModel dodel)
    {
        // Here you will get data in model
    }
syed mohsin
  • 2,948
  • 2
  • 23
  • 47
0

It is always better to use strongly typed view's. Only what all things under the form tag is bind to corresponding model, the asp.net bind html control's to model by there name attribute. so if you want the whole model to be intact pass the model to view and keep everything in hiddenfield's under the form tag.

titan61
  • 33
  • 7