I have a problem in mvc3. Im not sure this is specifically mvc3 but, Im currently using that with razor engine. Anyway, the problem that I am facing is, I have a form, I use the TextBoxFor, CheckBoxFor, etc. to render it. The rendering is working flawless, except, when I try to post the data, I basically post an empty form with null values.
Here is my model:
public class SendReplyPmForm : PM
{
public new string Text { get; set; }
public bool IsOriginalDelete { get; set; }
public int ReplyNr { get; set; }
public string ReceiverName { get; set; }
}
I have an extra viewmodel layer between the view and the model and it contains an extra paramater regarding this model
public class IndexViewModel
{
public SendReplyPmForm SendReplyPmForm { get; set; }
...
here is my view
#using (Html.BeginForm("SendReply", "Pm", FormMethod.Post, new { id = "formSendMsg" }))
{
#Html.TextBoxFor(model => model.SendReplyPmForm.ReceiverName, new { id = "ReceiverName" })
<span id="spanChkText">Delete Original Message: #Html.CheckBoxFor(model => model.SendReplyPmForm.IsOriginalDelete, new { id = "chkIsOriginalDelete", value = 1 })</span>
#{Html.RenderPartial("~/Areas/Forums/Views/Shared/Toolbar.cshtml");}
<span class="spanLabel">Message</span>
#Html.TextAreaFor(model => model.SendReplyPmForm.Text, new { id = "Text", rows = "10", cols = "65" })
#{Html.RenderPartial("temp.cshtml");}
#Html.HiddenFor(model => model.SendReplyPmForm.ReplyNr, new { id = "inputReplyNr", value = 0 })
<input type="submit" value="Send" />
}
and here i have the controller
[HttpPost]
public ActionResult SendReply(SendReplyPmForm SendReplyForm) {
var ViewModel = new IndexViewModel();
.
.
.
return View("Index", ViewModel);
}
The strange thing is, if I use pure HTML instead of the Html helpers, then the post is going smoothly without any problem.
I read this article (ASP.NET MVC’s Html Helpers Render the Wrong Value!) before I post this, but im not quite sure, that I have the same issue. (f.e.: I dont have action in my controller, that has the same name), but the fact that is also working with pure Html that makes me think.
Do you guys have any idea, how can I use this form with the Html helpers?
I believe your problem is the same as here, so you need to add a prefix:
[HttpPost]
public ActionResult SendReply([Bind(Prefix="SendReplyPmForm")]SendReplyPmForm SendReplyForm)
{
...
}
Related
Very simply I have data in a table on a server that does not appear when my ASP.NET MVC page is compiled into HTML.
I know everything on the backend works, because on other views there is no issue, but for some reason on this one page it doesn't work.
I suspect it has something to do with my model having two classes in it, because this is the only page to do that, but I'm not really sure as I am a novice at MVC.
Here's the Model, which I'll refer to as ModelFile.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Project.Subgroup.Models
{
public class ClassIActuallyNeed
{
public int Id { get; set; }
public string Html { get; set; } //<---This is the data I want
public string Version { get; set; }
public bool Deleted { get; set; }
}
public class ClassMyFriendInsistsINeed
{
public int Id { get; set; }
public string Name { get; set; }
public byte[] Signature { get; set; }
public bool Deleted { get; set; }
public virtual ClassIActuallyNeed ClassIActuallyNeed { get; set; }
}
}
...and the Controller which is called MainController.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Project.Models;
using Project.Subgroup.Models;
using System.Data.Entity;
using Project.Models.Authentication;
namespace Project.Subgroup.Controllers
{
public class MainController : Controller
{
private MyDatabase context = new MyDatabase();
// GET: Lobby/Home
public ActionResult Index()
{
return View();
}
[HttpGet]
public ActionResult FormPage()
{
return View();
}
[HttpPost]
public ActionResult FormPage(ClassIActuallyNeed model)
{
if (ModelState.IsValid)
{
using (var context = new MyDatabase())
{
var modelfile = new ModelFile
{
Name = model.Name,
Signature = model.Signature,
ClassIActuallyNeedId = model.ClassIActuallyNeedId
};
}
}
return View(model);
}
}
}
...and finally the view, which is FormPage.cshtml:
#model Project.Models.ClassIActuallyNeed
#{
ViewBag.Title = "My Page";
Layout = "~/Subgroup/Views/Shared/_Layout.cshtml";
}
<h2 >#ViewBag.Title</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.DisplayFor(model => model.Html) //<---- the problem
//There is other form stuff in here
}
The "Html" data is literally just a string containing HTML that I want plopped into my webpage. It's the only line in that table, and when I use "DisplayNameFor" instead of "DisplayFor", it successfully puts the name "Html" on my page.
Sorry for the code vomit, I cut out everything I knew was unrelated but I just can't really pin down exactly where my problem is. There are no errors of any kind in visual studio or in the console. Everything else on the page works totally fine including my JS stuff.
Edit: I appreciate all the input so far. I know that the problem is not that I don't have the model populated, as it is populated by the remote database. This works on every other page.
As I suspected the RequestVerificationToken is definitely supposed to be there, and is unrelated.
Also to clarify: the issue is not that it is displaying unformatted text instead of HTML. The issue is that it is displaying nothing at all.
You have 2 issues currently that I can see:
You're not populating your model with any data
[HttpGet]
public ActionResult FormPage()
{
//you need to pass the view some data, otherwise your model in your view
//will be null and you wont get any output (which is what you're seeing now)
ClassIActuallyNeed model = null;
//hardcoded:
//model = new ClassIActuallyNeed
//{
// Id = 1,
// Html = "<h1>Hello</h1>",
// Version = "something,
// Deleted = false
//};
//an example of using your context to fetch your model
using(var context = new MyDatabase())
{
var id = 1
model = context.ClassIActuallyNeeds.Single(x => x.Id == id);
}
return View(model);
}
You're not rendering the html string as html
Html.DisplayFor(model => model.Html) will render the this property as plain text on the page so instead of seeing Hello formatted in a <h1> tag, you'll see <h1>Hello</h1> as plain text on the page. The framework does this to protect against injection attacks which I'd suggest you read up on a bit however that's out of scope as far as this post goes. To have the html string actually rendered, use Html.Raw(model => model.Html)
As an additional side note, the
<input name="__RequestVerificationToken" type="hidden" value="[a bunch of junk characters here]">
you're seeing is a result of you using a #Html.AntiForgeryToken(). The antiforgery token is used to protect against CSRF attacks which I'd also suggest you read up on (security is important!). Since this view does not have any editable data in it (that's an assumption I'm making based on you using DisplayFor), there's no reason I see to have a form (Html.BeginForm) in your view or a AntiForgeryToken. If this data is editable and can be posted back to the server, then disregard that and both of those 2 pieces likely need to stay in place.
With the controller action above, your view could simply look like the following to display your data:
#model Project.Models.ClassIActuallyNeed
#{
ViewBag.Title = "My Page";
Layout = "~/Subgroup/Views/Shared/_Layout.cshtml";
}
<h2 >#ViewBag.Title</h2>
#Html.Raw(model => model.Html)
If this data needs to be editable then it would look more like
#model Project.Models.ClassIActuallyNeed
#{
ViewBag.Title = "My Page";
Layout = "~/Subgroup/Views/Shared/_Layout.cshtml";
}
<h2 >#ViewBag.Title</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.Id)
#Html.HiddenFor(model => model.Version)
#Html.HiddenFor(model => model.Deleted)
#Html.EditorFor(model => model.Html)
<input type="submit" value="Submit">
}
Source error: Line 22: #Html.TextBoxFor(model =>
model.DailyCurrencyRates___BuyingCurrency, new { #id = "test", #class
= "form-control" })
I am stuck on this issue for days and cannot get round this error. I simply want to render a partial view with the items for parent class. below is my code: Please ask for more info if needed.
Controller
public ActionResult AddRecord(int index)
{
return PartialView("_AddItem", new ForexItem { Index = index});
}
Parent View
#foreach (ForexItem item in Model.ForexItems)
{
Html.RenderPartial("_AddItem", item);
}
Partial View
#model F.Models.Entities.ForexItem
#Html.TextBoxFor(model => model.DailyCurrencyRates___BuyingCurrency, new { #id = "test", #class = "form-control" })
Model
public partial class ForexItem
{
public int ID { get; set; }
[NotMapped]
[StringLength(1000)]
[Display(Name = "Buying")]
public string DailyCurrencyRates___BuyingCurrency { get; set; }
[NotMapped]
public int Index { get; set; }
}
I obtained that same vague, obscure error when I increased the number of underscores in a model property name from 1 to 2. Note that the error did not occur for the LabelFor Helper directly before the TextBoxFor helper, but just in the TextBoxFor helper, same as you got. (I notice your property name ("DailyCurrencyRates___BuyingCurrency") has 3 underscores.) It then went away when I removed the extra underscore from the property name. It was as though with the extra underscore, Razor could not find the property name, so it just searched for (generic) "name" instead, which it also could not find.
It may be a typo, but it seems to me that you should change Model.ForexItems to Model.ForexItem - no s. Based on your submitted code.
… or maybe just use Model since you already put ForexItem in as that?
Parent View
#foreach (ForexItem item in Model)
{
Html.RenderPartial("_AddItem", item);
}
A strongly typed view has a <form> and on submitting <form> I am expecting it should return updated value in model but it is not the case. I couldn't figure out what it is happening.
View Mode:
public class HomeLoanViewModel
{
public Lead_Options leadOption { get; set; }
public Lead HomeLoanLead {get;set;}
public HomeLoanViewModel()
{
this.leadOption= new Lead_Options();
this.HomeLoanLead= new Lead();
}
}
and Lead class inside ViewModel is as below:
public partial class Lead
{
public string Lead_id { get; set; }
public string Income { get; set; }
[NotMapped]
public List<SelectListItem> Income_Binder
{
get
{
return new List<SelectListItem>()
{
new SelectListItem(){ Value="", Text="Please select...", Selected=true },
new SelectListItem(){ Value="$0 - $30,000", Text="$0 - $30,000" },
new SelectListItem(){ Value="$30,001 - $40,000", Text="$30,001 - $40,000" },
new SelectListItem(){ Value="$40,001 - $50,000", Text="$40,001 - $50,000"},
new SelectListItem(){ Value="$50,001 - $60,000", Text="$50,001 - $60,000"},
new SelectListItem(){ Value="$60,001 - $70,000", Text="$60,001 - $70,000"},
new SelectListItem(){ Value="$70,001 - $80,000", Text="$70,001 - $80,000"},
new SelectListItem(){ Value="$80,001 - $90,000", Text="$80,001 - $90,000"},
new SelectListItem(){ Value="$90,001 - $100,000", Text="$90,001 - $100,000"},
new SelectListItem(){ Value="$100,001 - $150,000", Text="$100,001 - $150,000"},
new SelectListItem(){ Value="$150,000+", Text="$150,000+"}
};
}
}
}
Controller & Action:
public class HomeLoanController : ParentController
{
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Submit(FormCollection form)
{
Session["loan_type"] = form.GetValue("Type").AttemptedValue;
Session["m_I_need_to"] = form.GetValue("LoanPurpose").AttemptedValue;
Session["m_The_property_is_a"] = form.GetValue("LoanFor").AttemptedValue;
Session["m_My_time_frame_to_buy_or_refinance_is"] = form.GetValue("LoanTimeFrame").AttemptedValue;
// return View("LeadContact", new HomeLoanViewModel());
return RedirectToAction("LeadContact");
}
[HttpGet]
public ActionResult LeadContact(HomeLoanViewModel model)
{
return View(model);
}
}
View:
#using HMC.Common.Utilities;
#model HMC.Common.ViewModel.HomeLoanViewModel
#{
ViewBag.Title = "LeadContact";
Layout = "~/Views/_Base.cshtml";
}
<form class="wrapper minheight homeloan-form border-top" id="homeloan-form" method="post" action="" novalidate="novalidate">
<label>Total Annual Income</label>
#Html.DropDownListFor(m => m.HomeLoanLead.Income, Model.HomeLoanLead.Income_Binder, new { required = "", aria_required = "true", name = "interestratetype" })
#Html.HiddenFor(m => m.HomeLoanLead.Income)
<div class="formnav row">
<button class="btn btn-large">Show Top Home Loans <i class="fa fa-chevron-right"></i></button>
</div>
</form>
EDIT:
From previous page/ view request come to Submit Action of controller, then it redirect to LeadContact. This is view where I m passing model and post back want to receive updated values.
This type of issue is common when using ViewModels or strongly typed views with models. Here's why...
When a post back happens the model binder eventually gets called prior to the controller getting called for the post back. If the controller is accepting a class (model or viewmodel) as an input parameter, then MVC will first create an instance of the class using the null constructor. Then the model binder will take the HTML Query string (name value pairs) and attempt to fill in the model/view model properties based on the name value pairs. If the binder cannot find the proper Name matches it simply doesn't do anything (which is proper behavior), as a result the symptoms of this are "Hey I missing data that I know I posted from the view".
The best way to debug this is 1) Set a breakpoint on the controller's action method. 2) Go to the client side and press F12 to view the network post. 3) Start the post back and notice the name value pairs sent from the browser. Upon breaking at the controller entry go do Debug/Windows/Locals and look at the model portion of the controller parameters. You will see the same thing there as in the network side (proof they all made it back). Now look at the typed value, if anything is not there that should be there, it is simply because the post back and the model (Name values) did not match.
90% of the time the root cause is the first parameter of the DisplayFor, HiddenFor or other "For" elements is not pointing to the correct thing to be returned. This is why I like to use ViewModels..
Given:
public class HomeLoanViewModel
{
public Lead_Options leadOption { get; set; }
public Lead HomeLoanLead {get;set;}
public String SelectedValue {get;set;}
public HomeLoanViewModel()
{
this.leadOption= new Lead_Options();
this.HomeLoanLead= new Lead();
}
public void Post(){
//do all your post logic here
if(SelectedValue > XYZ) //do this
}
}
I would create the controller signature like this:
[HttpPost]
public ActionResult Submit(HomeLoanViewModel vm)
{
if (ModelState.IsValid){
vm.Post();
return View(vm);
}
return View(vm);
}
I would create the view like this:
#using HMC.Common.Utilities;
#model HMC.Common.ViewModel.HomeLoanViewModel
#{
ViewBag.Title = "LeadContact";
Layout = "~/Views/_Base.cshtml";
}
#Using Html.BeginForm(){
<label>Total Annual Income</label>
#Html.DropDownListFor(m => m.HomeLoanLead.SelectedValue, Model.HomeLoanLead.Income_Binder, new { required = "", aria_required = "true"})
<input type="submit/>
}
<div class="formnav row">
<button class="btn btn-large">Show Top Home Loans <i class="fa fa-chevron-right"></i></button>
</div>
Finally one other pointer, no sense in the SelectListItems Text and Value being the same, you could just as easily have set the value to in Int such as [1,2,3,4,5] for each of the choices. Look at the value as the identifier of the text field, this works especially well with databases that have ID for looking up field values.
I have a partial view to post comment for my article module on my main view for article detail. Model for comment has three required fields, ID (identity field), ArticleId and CommentText. (I am using Razor syntax)
I tried to pass ArticleId at controller in Create Action.
public ActionResult Create(ArticleComment articlecomment, string AID)
{
articlecomment.ArticleId = AID; //this is required
if (User.Identity.IsAuthenticated)
{
articlecomment.UserId = WebSecurity.CurrentUserId.ToString();
}
else
{
articlecomment.UserId = Constants.Anonymus;
}
articlecomment.CommentDate = DateTime.Now;
if (ModelState.IsValid)
{
db.ArticleComment.Add(articlecomment);
int success = db.SaveChanges();
if (success > 0)
{
return Content("<script language='javascript' type='text/javascript'>alert('Comment added successfully.');window.location.href='" + articlecomment.ArticleId + "';</script>");
}
else
{
return Content("<script language='javascript' type='text/javascript'>alert('Posting comment has failed, please try later.');window.location.href='" + articlecomment.ArticleId+ "';</script>");
}
}
return PartialView(articlecomment);
}
But still ModelState.IsValid is returning false. I have used following code and find that ModelState is getting ArticleId as null.
foreach (var modelStateValue in ViewData.ModelState.Values)
{
foreach (var error in modelStateValue.Errors)
{
// Do something useful with these properties
var errorMessage = error.ErrorMessage;
var exception = error.Exception;
}
}
I have also thought to set value for ArticleId using Hidden field using ViewBag but have not find any working code. I tried following:
#Html.HiddenFor(model => model.ArticleId, new { #value = ViewBag.Article })
and
#Html.HiddenFor(model => model.ArticleId, (object)ViewBag.Article)
My 'ParticalView' to post comment is:
#model Outliner.Models.ArticleComment
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="editor-label">
#* #Html.HiddenFor(model => model.ArticleId, new { #value = ViewBag.Article })
#Html.HiddenFor(model => model.ArticleId, (object)ViewBag.Article)*#
#Html.LabelFor(model => model.Comment)
<span class="error">#Html.ValidationMessageFor(model => model.Comment)</span>
</div>
#Html.TextAreaFor(model => model.Comment)
<input type="submit" value="Post" />
}
And this is how I am calling this partial view on 'ArticalDetail' view (my main view):
#Html.Action("Create", "ArticleComment")
I have passed required field value at controller for a View before, but I am facing issue for PartialView. What I am doing wrong and how can I make this work?
Edit After a try
As Satpal and Fals lead me to a direction, I tried their suggestions, and tried following:
TryUpdateModel(articlecomment);
and also
TryUpdateModel<ArticleComment>(articlecomment);
and also
TryValidateModel(articlecomment);
but I was still getting same validation error for ArticleId, then I checked in Watch and all tree methods I tried are returning False.
I also tried following:
UpdateModel(articlecomment);
and
UpdateModel<ArticleComment>(articlecomment);
above methods are generating an exception :
The model of type 'Outliner.Models.ArticleComment' could not be
updated.
Here is my model:
[Table("ArticleComments")]
public class ArticleComment
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public string ArticleId { get; set; }
public string UserId { get; set; }
[Required]
[Display(Name = "Comment")]
public string Comment { get; set; }
[Required]
[Display(Name = "Commented On")]
public DateTime CommentDate { get; set; }
}
I don't get it, why my model is not updating ... :(
It is quite late answer, but it should work.
Before ModelState.IsValid, add following
ModelState.Remove("ArticleId");
It will remove that field from validation.
You can try TryUpdateModel(articlecomment) once before checking ModelState.IsValid. However I have not tested it
After update any requerid field after the ModelBind you must call another method to update the validation.
You can use:
TryValidateModel(articlecomment);
or
TryUpdateModel<ArticleComment>(articlecomment);
To me it seems that your #Html.Action(...) code it invoking the action to create the partial view, like you said. If you are doing this it isn't the correct way to invoke a partial view. While it isn't uncommon for a action to return a partial view, it is normally via AJAX, in my experience, so you can just insert it into the DOM after it returns.
You can use the following method to render a partial view:
#{
Html.RenderPartial("_myPartialView",
new ArticleComment {ArticleId = model.Id});
}
This should render your partial view, pass your model to it so it can render properly. Then when the form is POST'ed to the server it should create the model from the form data. You shouldn't need the AID parameter as it is part of your ArticleComment model.
I can't seem to figure out how to send back the entire ViewModel to the controller to the 'Validate and Save' function.
Here is my controller:
[HttpPost]
public ActionResult Send(BitcoinTransactionViewModel transaction)
{
}
Here is the form in the view:
<li class="check">
<h3>Transaction Id</h3>
<p>#Html.DisplayFor(m => m.Transaction.TransactionId)</p>
</li>
<li class="money">
<h3>Deposited Amount</h3>
<p>#Model.Transaction.Amount.ToString() BTC</p>
</li>
<li class="time">
<h3>Time</h3>
<p>#Model.Transaction.Time.ToString()</p>
</li>
#using (Html.BeginForm("Send", "DepositDetails", FormMethod.Post, new { transaction = Model }))
{
#Html.HiddenFor(m => m.Token);
#Html.HiddenFor(m => m.Transaction.TransactionId);
#Html.TextBoxFor(m => m.WalletAddress, new { placeholder = "Wallet Address", maxlength = "34" })
<input type="submit" value="Send" />
#Html.ValidationMessage("walletAddress", new { #class = "validation" })
}
When i click on submit, the conroller contains the correct value of the walletAddress field but transaction.Transaction.Time, transaction.Transaction.Location, transaction.Transaction.TransactionId are empty.
Is there a way i could pass the entire Model back to the controller?
Edit:
When i dont even receive the walletAddress in the controller. Everything gets nulled!
When i remove this line alone: #Html.HiddenFor(m => m.Transaction.TransactionId);
it works and i get the Token property on the controller, but when i add it back, all the properties of the transaction object on the controller are NULL.
Here is the BitcoinTransactionViewModel:
public class BitcoinTransactionViewModel
{
public string Token { get; set; }
public string WalletAddress { get; set; }
public BitcoinTransaction Transaction { get; set; }
}
public class BitcoinTransaction
{
public int Id { get; set; }
public BitcoinTransactionStatusTypes Status { get; set; }
public int TransactionId { get; set; }
public decimal Amount { get; set; }
public DateTime Time { get; set; }
public string Location { get; set; }
}
Any ideas?
EDIT: I figured it out, its in the marked answer below...
OK, I've been working on something else and bumpend into the same issue all over again.
Only this time I figured out how to make it work!
Here's the answer for anyone who might be interested:
Apparently, there is a naming convention. Pay attention:
This doesn't work:
// Controller
[HttpPost]
public ActionResult Send(BitcoinTransactionViewModel transaction)
{
}
// View
#using (Html.BeginForm("Send", "DepositDetails", FormMethod.Post, new { transaction = Model }))
{
#Html.HiddenFor(m => m.Token);
#Html.HiddenFor(m => m.Transaction.TransactionId);
.
.
This works:
// Controller
[HttpPost]
public ActionResult Send(BitcoinTransactionViewModel **RedeemTransaction**)
{
}
// View
#using (Html.BeginForm("Send", "DepositDetails", FormMethod.Post, new { **RedeemTransaction** = Model }))
{
#Html.HiddenFor(m => m.Token);
#Html.HiddenFor(m => m.Transaction.TransactionId);
.
.
In other words - a naming convention error! There was a naming ambiguity between the Model.Transaction property and my transaction form field + controller parameter. Unvelievable.
If you're experiencing the same problems make sure that your controller parameter name is unique - try renaming it to MyTestParameter or something like this...
In addition, if you want to send form values to the controller, you'll need to include them as hidden fields, and you're good to go.
The signature of the Send method that the form is posting to has a parameter named transaction, which seems to be confusing the model binder. Change the name of the parameter to be something not matching the name of a property on your model:
[HttpPost]
public ActionResult Send(BitcoinTransactionViewModel model)
{
}
Also, remove the htmlAttributes parameter from your BeginForm call, since that's not doing anything useful. It becomes:
#using (Html.BeginForm("Send", "DepositDetails", FormMethod.Post))
Any data coming back from the client could have been tampered with, so you should only post back the unique ID of the transaction and then retrieve any additional information about it from your data source to perform further processing. You'll also want to verify here that the user posting the data has access to the specified transaction ID since that could've been tampered with as well.
This isn't MVC specific. The HTML form will only post values contained within form elements inside the form. Your example is neither inside the form or in a form element (such as hidden inputs). You have to do this since MVC doesn't rely on View State. Put hidden fields inside the form:
#Html.HiddenFor(x => x.Transaction.Time)
// etc...
Ask yourself though.. if the user isn't updating these values.. does your action method require them?
Model binding hydrates your view model in your controller action via posted form values. I don't see any form controls for your aforementioned variables, so nothing would get posted back. Can you see if you have any joy with this?
#using (Html.BeginForm("Send", "DepositDetails", FormMethod.Post, new { transaction = Model }))
{
#Html.TextBoxFor(m => m.WalletAddress, new { placeholder = "Wallet Address", maxlength = "34" })
#Html.Hidden("Time", Model.Transaction.Time)
#Html.Hidden("Location", Model.Transaction.Location)
#Html.Hidden("TransactionId", Model.Transaction.TransactionId)
<input type="submit" value="Send" />
#Html.ValidationMessage("walletAddress", new { #class = "validation" })
}
Try to loop with the folowing statement not with FOREACH
<table>
#for (var i = 0; i < Model.itemlist.Count; i++)
{
<tr>
<td>
#Html.HiddenFor(x => x.itemlist[i].Id)
#Html.HiddenFor(x => x.itemlist[i].Name)
#Html.DisplayFor(x => x.itemlist[i].Name)
</td>
</tr>
}
</table>
Try Form Collections and get the value as. I think this may work.
public ActionResult Send(FormCollection frm)
{
var time = frm['Transaction.Time'];
}
Put all fields inside the form
#using (Html.BeginForm("Send", "DepositDetails", FormMethod.Post))
and make sure that the model
BitcoinTransactionViewModel
included in view or not?
Can you just combine those 2 models you have? Here's how I do it with one model per view...
1. I use Display Templates from view to view so I can pass the whole model as well as leave data encrypted..
2. Setup your main view like this...
#model IEnumerable<LecExamRes.Models.SelectionModel.GroupModel>
<div id="container">
<div class="selectLabel">Select a Location:</div><br />
#foreach (var item in Model)
{
#Html.DisplayFor(model=>item)
}
</div>
3. Create a DisplayTemplates folder in shared. Create a view, naming it like your model your want to pass because a DisplayFor looks for the display template named after the model your using, I call mine GroupModel. Think of a display template as an object instance of your enumeration. Groupmodel Looks like this, I'm simply assigning a group to a button.
#model LecExamRes.Models.SelectionModel.GroupModel
#using LecExamRes.Helpers
#using (Html.BeginForm("Index", "Home", null, FormMethod.Post))
{
<div class="mlink">
#Html.AntiForgeryToken()
#Html.EncryptedHiddenFor(model => model.GroupKey)
#Html.EncryptedHiddenFor(model => model.GroupName)
<p>
<input type="submit" name="gbtn" class="groovybutton" value=" #Model.GroupKey ">
</p>
</div>
}
4. Here's the Controller.
*GET & POST *
public ActionResult Index()
{
// Create a new Patron object upon user's first visit to the page.
_patron = new Patron((WindowsIdentity)User.Identity);
Session["patron"] = _patron;
var lstGroups = new List<SelectionModel.GroupModel>();
var rMgr = new DataStoreManager.ResourceManager();
// GetResourceGroups will return an empty list if no resource groups where found.
var resGroups = rMgr.GetResourceGroups();
// Add the available resource groups to list.
foreach (var resource in resGroups)
{
var group = new SelectionModel.GroupModel();
rMgr.GetResourcesByGroup(resource.Key);
group.GroupName = resource.Value;
group.GroupKey = resource.Key;
lstGroups.Add(group);
}
return View(lstGroups);
}
[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult Index(SelectionModel.GroupModel item)
{
if (!ModelState.IsValid)
return View();
if (item.GroupKey != null && item.GroupName != null)
{
var rModel = new SelectionModel.ReserveModel
{
LocationKey = item.GroupKey,
Location = item.GroupName
};
Session["rModel"] = rModel;
}
//So now my date model will have Group info in session ready to use
return RedirectToAction("Date", "Home");
}
5. Now if I've got alot of Views with different models, I typically use a model related to the view and then a session obj that grabs data from each model so in the end I've got data to submit.
The action name to which the data will be posted should be same as the name of the action from which the data is being posted. The only difference should be that the second action where the data is bein posted should have [HttpPost] and the Posting method should serve only Get requests.