passing values from view to Controller N then to other View - asp.net-mvc

Customer:
<p></p>
<p></p>
<div> <% foreach (var item in Model)
{ %>
You are viewing Users of Customer: <%:item.Customer %>
<%break; %>
<%} %></div>
<p></p>
<% Html.RenderPartial("EditUsers", Model); %>
<p>
<%: Html.ActionLink("Create New", "Create", "Profile", null, null)%>
</p>
Now i got to pass the <%:item.Customer %> through the %: Html.ActionLink("Create New", "Create", "Profile", null, null)%> and that should be displayed in the Create view
here is the Controller n i will give the Create view too
Controller:
public ActionResult Create()
{
return View();
}
[HttpPost]
public ActionResult Create(string UserName, string Password, string FirstName, string LastName,
string MiddleInitial, string Email,string Telephone, bool IsAdmin, bool IsSubAdmin)
{
UserDAL userDALObject = new UserDAL();
tblUser newUser = new tblUser();
newUser.Customer = customerNumber;
newUser.UserName = UserName;
newUser.Password = Password;
newUser.FirstName = FirstName;
newUser.LastName = LastName;
newUser.MiddleInitial = MiddleInitial;
newUser.Email = Email;
newUser.Telephone = Telephone;
newUser.IsAdmin = IsAdmin;
newUser.IsSubAdmin = IsSubAdmin;
userDALObject.AddUserDetails(newUser);
TempData["UserCreationMsg"] = string.Format("User named :{0}, is created",UserName);
return View();
}
public ActionResult EditUser(string id)
{
UserDAL userDALObject = new UserDAL();
tblUser userDetails = userDALObject.GetUser(Int32.Parse(id));
TempData["EditUserId"] = id;
return View(userDetails);
}
the Create View
<%if(TempData["UserCreationMsg"] != null)%>
<%{ %>
<%: TempData["UserCreationMsg"].ToString() %>
<%} %>
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<div class="editor-label">
<%: Html.LabelFor(model => model.UserName) %>
</div>
<div class="editor-field">
<%: Html.TextBox("UserName") %>
<%: Html.ValidationMessageFor(model => model.UserName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Password) %>
</div>
<div class="editor-field">
<%: Html.Password("Password") %>
<%: Html.ValidationMessageFor(model => model.Password) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FirstName) %>
</div>
<div class="editor-field">
<%: Html.TextBox("FirstName") %>
<%: Html.ValidationMessageFor(model => model.FirstName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.LastName) %>
</div>
<div class="editor-field">
<%: Html.TextBox("LastName") %>
<%: Html.ValidationMessageFor(model => model.LastName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.MiddleInitial) %>
</div>
<div class="editor-field">
<%: Html.TextBox("MiddleInitial") %>
<%: Html.ValidationMessageFor(model => model.MiddleInitial) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Email) %>
</div>
<div class="editor-field">
<%: Html.TextBox("Email") %>
<%: Html.ValidationMessageFor(model => model.Email) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Telephone) %>
</div>
<div class="editor-field">
<%: Html.TextBox("Telephone") %>
<%: Html.ValidationMessageFor(model => model.Telephone) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.IsAdmin) %>
</div>
<div class="editor-field">
<%: Html.CheckBox("IsAdmin") %>
<%: Html.ValidationMessageFor(model => model.IsAdmin) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.IsSubAdmin) %>
</div>
<div class="editor-field">
<%: Html.CheckBox("IsSubAdmin") %>
<%: Html.ValidationMessageFor(model => model.IsSubAdmin) %>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>

What exactly is your issue?
On the side point, you should be using Model Binding to pass a person object to the CreateView action method rather than passing each property separately. It will reduce a lot of your code. Search Model Binding for more details.

Related

how to simultaneously pass A model as well as a File to the controller?

i have a reports model in my MVC project. Now i have to send a file to the controller simultaneously. I am using HttpPostedFileBase as parameter with my reports model.
Reports Model is :
Public Class ReportsModel
Public Sub New()
Authentication = "private"
End Sub
Private UploadDate_ As String
<Display(Name:="ID")> _
Public Property id As UInteger
<Display(Name:="Serial Number")> _
Public Property Srno As UInteger
<Display(Name:="User Name")> _
Public Property UserName As String
<Display(Name:="Details")> _
Public Property Details As String
End Class
And My Controller is :
<HttpPost()> _
<AllowAnonymous()> _
<ValidateAntiForgeryToken()> _
Public Function EditReport(ByVal mdl As ReportsModel, ByVal FileUpl As HttpPostedFileBase ) As ActionResult
Return View(mdl)
End Function
Here is my View:
<% Using Html.BeginForm() %>
<%: Html.AntiForgeryToken() %>
<%: Html.ValidationSummary(True) %>
<fieldset>
<legend>ReportsModel</legend>
<%: Html.HiddenFor(Function(model) model.id) %>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.Srno) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(Function(model) model.Srno) %>
<%: Html.ValidationMessageFor(Function(model) model.Srno) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.UserName) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(Function(model) model.UserName) %>
<%: Html.ValidationMessageFor(Function(model) model.UserName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.Details) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(Function(model) model.Details) %>
<%: Html.ValidationMessageFor(Function(model) model.Details) %>
</div>
<%--This Code Below is running correctly on passing it , But not with Reports Model--%>
<form action="/phed/EditReport" method="post" enctype="multipart/form-data">
<label for="FileUpl1">Upload File: </label>
<input type="file" name="FileUpl" id="FileUpl" />
<span style="color: red;"><%:TempData("Message")%></span>
<p>
<input type="submit" value="Save" />
</p>
</form>
</fieldset>
<% End Using %>
How to send this FileUpl along with ReportsModel to the controller ? I Can Not change reports Model.
I got it. I have Change the form action and enctype to "multipart/form-data". Like:
<div>
<form action="/phed/EditReport" method="post" enctype="multipart/form-data">
<%: Html.AntiForgeryToken() %>
<%: Html.ValidationSummary(True) %>
<fieldset>
<legend>ReportsModel</legend>
<%: Html.HiddenFor(Function(model) model.id) %>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.Details) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(Function(model) model.Details) %>
<%: Html.ValidationMessageFor(Function(model) model.Details) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.BillsOfMonth) %>
</div>
<div class="editor-field">
<%: Html.TextBox("BillsOfMonth", Model.BillsOfMonth, New With {Key .class = "monthpicker"})%>
<%: Html.ValidationMessageFor(Function(model) model.BillsOfMonth) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.UplDate) %>
</div>
<div class="editor-field">
<%: Html.TextBox("UplDate", Model.UplDate, New With {Key .class = "datepicker"})%>
<%: Html.ValidationMessageFor(Function(model) model.UplDate) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.Authentication) %>
</div>
<div class="editor-field">
<%: Html.DropDownList("Authentication", New List(Of SelectListItem) From { _
New SelectListItem With {.Text = "public", .Value = "public"}, _
New SelectListItem With {.Text = "private", .Value = "private"}})%>
<%: Html.ValidationMessageFor(Function(model) model.Authentication) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.Download) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(Function(model) model.Download, New With {Key .readonly = "readonly"})%>
<%: Html.ValidationMessageFor(Function(model) model.Download) %>
</div>
<label for="FileUpl1">Upload File: </label>
<input type="file" name="FileUpl" id="FileUpl" />
<span style="color: red;"><%:TempData("Message")%></span>
<input type="submit" class="sort-submit" value="Upload File" />
</fieldset>
</form>
</div>
It seems you create a form nested to another form which is not allowed in HTML, so if you want to upload your file, you have to remove the second Form. The BeginForm method renders a form that will be handled by a controller action method.
You can use this method in a using block. In that case, the method renders the closing tag at the end of the using block.
And you can do like this:
<% Using Html.BeginForm("EditReport","phed",Nothing,FormMethod.Post, New With {.enctype="multipart/form-data"}) %>
<%: Html.AntiForgeryToken() %>
<%: Html.ValidationSummary(True) %>
<fieldset>
<legend>ReportsModel</legend>
<%: Html.HiddenFor(Function(model) model.id) %>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.Srno) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(Function(model) model.Srno) %>
<%: Html.ValidationMessageFor(Function(model) model.Srno) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.UserName) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(Function(model) model.UserName) %>
<%: Html.ValidationMessageFor(Function(model) model.UserName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.Details) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(Function(model) model.Details) %>
<%: Html.ValidationMessageFor(Function(model) model.Details) %>
</div>
<%--This Code Below is running correctly on passing it , But not with Reports Model--%>
<label for="FileUpl1">Upload File: </label>
<input type="file" name="FileUpl" id="FileUpl" />
<span style="color: red;"><%:TempData("Message")%></span>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% End Using %>
I hope it will help.

how to bind data to label in asp.net mvc3

I have three model Classes(code first)
ProductGroup(p)->product(c)(list of produGroups comes in drop down list while creating a new product),
Now my requirement is,
Product(p)->PreferedLocation(c),
when I select preferedLocation(Create action) link ,I have to fill the details for the particular product.Means first I need to display single product name in Label like Product:Mango
In controller
public ActionResult PreferedLocation()
{
ViewBag.ProductID = new SelectList(db.Products,"ProductID","Name");
//ViewBag.CountryID = new SelectList(db.Countries, "CountryID", "Name");
return View();
}
//
// POST: /PreferedLocation/Create
[HttpPost]
public ActionResult PreferedLocation(PreferredLocation preferredlocation)
{
if (ModelState.IsValid)
{
db.PreferredLocations.Add(preferredlocation);
db.SaveChanges();
return RedirectToAction("Index");
}
// ViewBag.ProductID = new SelectList(db.Products, "ProductID", "Name", preferredlocation.ProductID);
return View(preferredlocation);
}
In View:
<div class="editor-field">
<%: Html.EditorFor(model => model.Name) %>
<%: Html.ValidationMessageFor(model => model.Name) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.StreetAdress) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.StreetAdress) %>
<%: Html.ValidationMessageFor(model => model.StreetAdress) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Description) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.Description) %>
<%: Html.ValidationMessageFor(model => model.Description) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Latitude) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.Latitude) %>
<%: Html.ValidationMessageFor(model => model.Latitude) %>
</div>
<div class="display-label">product</div>
<div class="display-field">
<%: Html.LabelFor(model=>Model.Product.Name) %>
<%: Html.ValidationMessageFor(model => model.ProductID) %>
</div>
Here I tried Code for idsplaying product name in label
but instead of product name I got output as
product
Product Name.
What modifications I have to do.
Use DisplayFor instead of LabelFor.

ASP.NET MVC DropDownList and HTML Attributes

I am having a dropdownlist in my application in edit form.
But somewhere I was wrong.
HomeController.cs
ViewData["RealizatorID"] = from r in db.tGlavnas
select new SelectListItem { Text = r.Realizator.ImeRealizatora,
Value = r.Realizator.ImeRealizatora, Selected = (r.RealizatorID == id) };
Edit.aspx
<div class="editor-label">
<%: Html.LabelFor(model => model.RealizatorID) %>
</div>
<div class="editor-field">
<%: Html.DropDownList("RealizatorID")%>
<%: Html.ValidationMessageFor(model => model.RealizatorID) %>
</div>
When recording changes in Edit.aspx page report following error to me:
There is no ViewData item of type 'IEnumerable' that has the key 'RealizatorID'.
I suggest you to do the following:
Controller:
ViewData["SelRealizator"] = from r in db.tGlavnas
select new SelectListItem { Text = r.Realizator.ImeRealizatora,
Value = r.Realizator.ImeRealizatora, Selected = (r.RealizatorID == id) };
View:
<div class="editor-label">
<%: Html.LabelFor(model => model.RealizatorID) %>
</div>
<div class="editor-field">
<%: Html.DropDownListFor(model => model.RealizatorID, ViewData["SelRealizator"] as IEnumerable<SelectListItem>)%>
<%: Html.ValidationMessageFor(model => model.RealizatorID) %>
</div>
Full code:
public ActionResult Edit(int id)
{
var log = db.tGlavnas.Single(lo => lo.RedniBroj == id);
ViewData["SelRealizator"] = from r in db.tGlavnas select new SelectListItem { Text = r.Realizator.ImeRealizatora, Value = r.Realizator.ImeRealizatora, Selected = (r.RealizatorID == id) };
return View(log);
}
I don't write Post method yet.
Edit.aspx
<h2>Edit</h2>
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.RedniBroj) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.RedniBroj) %>
<%: Html.ValidationMessageFor(model => model.RedniBroj) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.DatumPrijema) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.DatumPrijema) %>
<%: Html.ValidationMessageFor(model => model.DatumPrijema) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.DatumPredaje) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.DatumPredaje) %>
<%: Html.ValidationMessageFor(model => model.DatumPredaje) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.BrojID) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.BrojID) %>
<%: Html.ValidationMessageFor(model => model.BrojID) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.PredmetJavneNabavke) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.PredmetJavneNabavke) %>
<%: Html.ValidationMessageFor(model => model.PredmetJavneNabavke) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.VrstaID) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.VrstaID) %>
<%: Html.ValidationMessageFor(model => model.VrstaID) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.TipSredstvaID) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.TipSredstvaID) %>
<%: Html.ValidationMessageFor(model => model.TipSredstvaID) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.ProcenjenaVrednost) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.ProcenjenaVrednost) %>
<%: Html.ValidationMessageFor(model => model.ProcenjenaVrednost) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.PoKontuID) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.PoKontuID) %>
<%: Html.ValidationMessageFor(model => model.PoKontuID) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.RealizatorID) %>
</div>
<div class="editor-field">
<%: Html.DropDownListFor(model => model.RealizatorID, ViewData["SelRealizator"] as
IEnumerable<SelectListItem>)%>
<%: Html.ValidationMessageFor(model => model.RealizatorID) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.PonudjacID) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.PonudjacID) %>
<%: Html.ValidationMessageFor(model => model.PonudjacID) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Iznos) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Iznos, String.Format("{0:F}", Model.Iznos)) %>
<%: Html.ValidationMessageFor(model => model.Iznos) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.BrojRacuna) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.BrojRacuna) %>
<%: Html.ValidationMessageFor(model => model.BrojRacuna) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.DatumIsplate) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.DatumIsplate, String.Format("{0:g}", Model.DatumIsplate)) %>
<%: Html.ValidationMessageFor(model => model.DatumIsplate) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.JavnaNabSprovPostID) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.JavnaNabSprovPostID) %>
<%: Html.ValidationMessageFor(model => model.JavnaNabSprovPostID) %>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to List", "Index") %>
</div>

Upload with Strongly Typed View - Problem

I'm have a problem with Upload with strongly typed view in ASP.NET MVC.
The value of input (view) is coming null for the view. My code follow:
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm("Create", "DownloadsSub", FormMethod.Post, new { enctype = "multipart/form-data" }))
{%>
<%: Html.ValidationSummary(true)%>
<fieldset>
<legend>Informações do download</legend>
<div class="editor-label">
Selecione a categoria do download
</div>
<div class="editor-field">
<%: Html.DropDownList("IDCategoriaDownloads", (IEnumerable<SelectListItem>)ViewData["IDCategoriaDownloads"], "Categorias de downloads...")%>
<%: Html.ValidationMessageFor(model => model.IDCategoriaDownloads)%>
</div>
<div class="editor-label">
Selecione o formato do arquivo
</div>
<div class="editor-field">
<%= Html.DropDownList("IDFormatoArquivo", (IEnumerable<SelectListItem>)ViewData["IDFormatoArquivo"], "Formatos de arquivos...") %>
<%: Html.ValidationMessageFor(model => model.IDFormatoArquivo)%>
</div>
<div class="editor-label">
Título do download
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.TituloDownload)%>
<%: Html.ValidationMessageFor(model => model.TituloDownload)%>
</div>
<div class="editor-label">
Descrição do download
</div>
<div class="editor-field">
<%: Html.TextAreaFor(model => model.DescricaoDownload)%>
<%: Html.ValidationMessageFor(model => model.DescricaoDownload)%>
</div>
<div class="editor-label">
Data de Postagem
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.DataDownload)%>
<%: Html.ValidationMessageFor(model => model.DataDownload)%>
</div>
<div class="editor-label">
Selecione o arquivo para download
</div>
<div class="editor-field">
<input type="file" id="txtFile" name="txtFile" />
<%--<%: Html.TextBoxFor(model => model.CaminhoDownload) %>
<%: Html.ValidationMessageFor(model => model.CaminhoDownload)%>--%>
</div>
<div class="editor-label">
Quantidade inicial de cliques
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.HitsDownload)%>
<%: Html.ValidationMessageFor(model => model.HitsDownload)%>
</div>
<div class="editor-label">
Qual o tamanho do arquivo em bytes?
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.TamanhoDownload) %>
<%: Html.ValidationMessageFor(model => model.TamanhoDownload) %>
</div>
<div class="editor-label">
Possui direitos autorais?
</div>
<div class="editor-field">
<%= Html.DropDownList("StatusDireitosAutorais", (IEnumerable<SelectListItem>)ViewData["StatusDireitosAutorais"], "Selecione...")%>
<%: Html.ValidationMessageFor(model => model.StatusDireitosAutorais)%>
</div>
<div class="editor-label">
Direitos autorais (preencha apenas se houver)
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.CreditosDownload)%>
<%: Html.ValidationMessageFor(model => model.CreditosDownload)%>
</div>
<p>
<input type="submit" value="Salvar" />
</p>
</fieldset>
<% } %>
And the controller
[HttpPost]
public ActionResult Create(tbDownloads _novoDownload, HttpPostedFileBase arquivoUp)
{
//var arquivoUp = this.Request.Files[0];
string nomeArquivoSalvo = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FilesUpload", "Downloads");
nomeArquivoSalvo = Path.Combine(nomeArquivoSalvo, Path.GetFileName(arquivoUp.FileName));
arquivoUp.SaveAs(Server.MapPath("~/FilesUpload/Downloads/") + nomeArquivoSalvo);
_novoDownload.CaminhoDownload = nomeArquivoSalvo.ToString();
if (ModelState.IsValid)
{
modelo.AddTotbDownloads(_novoDownload);
modelo.SaveChanges();
return RedirectToAction("Sucesso", "Mensagens");
}
return View(_novoDownload);
}
Ideas?
Thanks for help!
The name of the HttpPostedFileBase property needs to match the name of the input field in the view.
In the view, you have called it "txtFile":
<div class="editor-field">
<input type="file" id="txtFile" name="txtFile" />
<%--<%: Html.TextBoxFor(model => model.CaminhoDownload) %>
<%: Html.ValidationMessageFor(model => model.CaminhoDownload)%>--%>
</div>
But in the controller you refer to it as:
[HttpPost]
public ActionResult Create(tbDownloads _novoDownload,
HttpPostedFileBase arquivoUp)
{ [...] }
If you change this to:
[HttpPost]
public ActionResult Create(tbDownloads _novoDownload,
HttpPostedFileBase txtFile)
{ [...] }
It should all work.

In MVC, one Edit HttpPost is working, the other one isn't. What am I missing?

Googling generally and on SO hasn't helped me yet, so:
I am building my first MVC application from scratch, going by the MVC Music Store example but instead building a little application where arena Fighters can be created and made to Fight each other. (Fighters and Fight have been made linked to underlying tables through EF).
I have controllers for both the Fighters and the Fights. The Edit Actionresult for Fights is working, but for Fighters it is not. When I hit the button to save my alterations I return to the associated Index page, but no changes have been committed. This is my question: why is this failing?
From BarracksController, with the faulty non-updating HttpPost Edit (should have been named FighterController, but neverthemind):
//
// GET: /Barracks/Edit
public ActionResult Edit(int id)
{
ViewData.Model = _FightDb.Fighters.Single(f => f.Id == id);
return View();
}
//
// POST: /Barracks/Edit
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
var fighter = _FightDb.Fighters.Single(f => f.Id == id);
try
{
UpdateModel(fighter, "Fighter");
var x = ViewData.GetModelStateErrors();
_FightDb.SaveChanges();
return RedirectToAction("Index");
}
catch
{
var viewModel = fighter;
return View(viewModel);
}
}
(As you can see, I've included the GetModelStateErrors trick from this SO question, but the result for x is null)
This is the controller that does work, FightController:
//
// GET: /Fights/Edit
public ActionResult Edit(int id)
{
var viewModel = new FightDetailsViewModel
{
Fight = _FightDb.Fights.Single(f => f.ID == id),
Fighters = _FightDb.Fighters.ToList()
};
return View(viewModel);
}
//
// POST: /Fights/Edit
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
var fight = _FightDb.Fights.Single(f => f.ID == id);
try
{
UpdateModel(fight, "Fight");
_FightDb.SaveChanges();
return RedirectToAction("Index");
}
catch
{
var viewModel = new FightDetailsViewModel
{
Fight = _FightDb.Fights.Single(f => f.ID == id),
Fighters = _FightDb.Fighters.ToList()
};
return View(viewModel);
}
}
This is edit.aspx for the Fighters: (Edited after comment)
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Mvc3_EF_BW_Fight.Models.Fighter>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="cphMain" runat="server">
<h2>Edit</h2>
<%: Html.EditorForModel() %>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="head" runat="server">
</asp:Content>
Which uses the following Fighter.ascx in Shared:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Mvc3_EF_BW_Fight.Models.Fighter>" %>
<% using (Html.BeginForm())
{%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fighter</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.Id) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Id) %>
<%: Html.ValidationMessageFor(model => model.Id) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FighterName) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FighterName) %>
<%: Html.ValidationMessageFor(model => model.FighterName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FighterStyleDescription) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FighterStyleDescription) %>
<%: Html.ValidationMessageFor(model => model.FighterStyleDescription) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FighterLongDescription) %>
</div>
<div class="editor-field">
<%: Html.TextAreaFor(model => model.FighterLongDescription) %>
<%: Html.ValidationMessageFor(model => model.FighterLongDescription) %>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
This is the edit.aspx for Fights
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Mvc3_EF_BW_Fight.ViewModels.FightDetailsViewModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="cphMain" runat="server">
<h2>Edit</h2>
<%: Html.EditorFor(model => model.Fight, new { Fighters = Model.Fighters })%>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="head" runat="server">
</asp:Content>
And this is the Fight.ascx:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Mvc3_EF_BW_Fight.Models.Fight>" %>
<% using (Html.BeginForm())
{%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.ID) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.ID) %>
<%: Html.ValidationMessageFor(model => model.ID) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FightName) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FightName) %>
<%: Html.ValidationMessageFor(model => model.FightName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Fighter1ID) %><br />
<%: Html.LabelFor(model => model.Fighter1Reference.Value.FighterName)%>
</div>
<div class="editor-field">
<%: Html.DropDownList("Fighter1ID", new SelectList(ViewData["Fighters"] as IEnumerable, "ID", "FighterName", Model.Fighter1ID))%>
<%: Html.ValidationMessageFor(model => model.Fighter1ID) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Fighter2ID) %>
</div>
<div class="editor-field">
<%: Html.DropDownList("Fighter1ID", new SelectList(ViewData["Fighters"] as IEnumerable, "ID", "FighterName", Model.Fighter1ID))%>
<%: Html.ValidationMessageFor(model => model.Fighter2ID) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Fighter1Login) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Fighter1Login) %>
<%: Html.ValidationMessageFor(model => model.Fighter1Login) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Fighter2Login) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Fighter2Login) %>
<%: Html.ValidationMessageFor(model => model.Fighter2Login) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FightStatusID) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FightStatusID) %>
<%: Html.ValidationMessageFor(model => model.FightStatusID) %>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
And this is my viewmodel for Fights:
public class FightDetailsViewModel
{
public Fight Fight { get; set; }
public List<Fighter> Fighters { get; set; }
}
There is no ViewModel for Fighters (none that is involved in this scenario, anyway).
I can post any code you may wish to see.
Edit: I've looked at Using ViewModel Pattern with MVC 2 Strongly Typed HTML Helpers and ASP.NET MVC 2 UpdateModel() is not updating values in memory or database , but i haven't seen a solution there yet.
Instead of this UpdateModel(fighter, "Fighter"); try calling the updte model just like this UpdateModel(fighter);. The difference is between the two edits that in case of Fighter your model is directly the Fighter so you do not need the name, while in case of the Fight you call the Editor for model.Fight so you need the name. See this question as well: asp.net mvc2 - how to get model and model.something in the same way in controller?

Resources