not able to see the view after postback - c#

Hi I have got a drop downlist that I am binding that one in controller I have got one button in view with that I am doing some validations that's working fine,
when I submit the button for validation check i am not able to get the view with error message. Instead of this I am getting error like this " The view 'PostValues' or its master was not found or no view engine supports the searched locations".
would any one help on why I am not able to get the view
here the view is strongly Typed view
and this is my code in controller.
public class CrossFieldsTxtboxesController : Controller
{
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index()
{
var model = NewMethod();
return View(model);
}
private static CrossFieldValidation NewMethod()
{
var model = new CrossFieldValidation
{
SelectedValue = "Amount",
Items = new[]
{
new SelectListItem { Value = "Amount", Text = "Amount" },
new SelectListItem { Value = "Pound", Text = "Pound" },
new SelectListItem { Value = "Percent", Text = "Percent" },
}
};
return model;
}
[HttpPost]
public ActionResult PostValues(CrossFieldValidation model1)
{
model1 = NewMethod();
if (!ModelState.IsValid)
{
return View(model1);
}
else
{
return RedirectToAction("Index");
}
}
}
and this is my view
#model MvcSampleApplication.Models.CrossFieldValidation
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm("PostValues", "CrossFieldsTxtboxes"))
{
#Html.ValidationSummary(true)
<div class ="editor-field">
#Html.TextBoxFor(m => m.TxtCrossField)
#Html.ValidationMessageFor(m=>m.TxtCrossField)
</div>
#Html.DropDownListFor(m=> m.SelectedValue , Model.Items)
<input id="PostValues" type="Submit" value="PostValues" />
}
would any one pls help on this...

This line
return View(model1);
looks for the view named exactly like the action in which it was called. Calling this line from PostValues action assumes there is a view PostValues.cshtml (which apparently does not exist). If you still want to use view Index - you should specify this explicitly:
if (!ModelState.IsValid)
{
return View("Index", model1);
}

As Andrei said. Alternatively, you can give your PostValues method an additional tag:
[HttpPost, ActionName("Index")]
public ActionResult PostValues(CrossFieldValidation model1)
{
if (!ModelState.IsValid)
{
return View(model1);
}
}

Related

How to pass checkbox value to controller in ASP.NET MVC

I am using
#Html.CheckBoxFor(model => model.AllowOrder, new { id = "allowOrder"})
Now I want to pass its value (whether checked or unchecked) to the controller. I am using html.BeginForm for posting back the data to controller. Every time I am getting its value as null in action method. Action method has below sample code.
public ActionResult index(bool isChecked)
{
// code here
}
isChecked property is passed in as null always. Any help please. TIA.
If you don't want to return to controller whole data model, but only one value then see code below:
public IActionResult IndexTest()
{
var model = new ViewModel() { AllowOrder = true };
return View(model);
}
[HttpPost]
public IActionResult IndexTest(bool isChecked)
{
// your code here...
return View("IndexTest", new ViewModel() { AllowOrder = isChecked} );
}
Using the onclick() to trace the checkbox state:
#model ViewModel
<script>
function onStateChange() {
var item = document.getElementById('allowOrder');
var chk = false;
if (item.checked) {
chk = true;
}
document.getElementById('isChecked').value = chk;
};
</script>
#using (Html.BeginForm())
{
#Html.Hidden("isChecked", Model.AllowOrder)
#Html.CheckBoxFor(r => Model.AllowOrder, new { id = "allowOrder", #onclick = "onStateChange()" })
<input id="Button" type="submit" value="Save" />
}
View:
#model <specifyModelhere>
#using(Html.BeginForm("index","<YourControllerNameHere>",FormMethod.Post))
{
#Html.CheckBoxFor(r => Model.AllowOrder)
<input id="Button" type="submit" value="Save" />
}
Controller:
public ActionResult index(<YourModelNameHere> model)
{
var ischecked = model.AllowOrder;
// code here
}
This way when you submit the form, the entire model will be posted back and you can receive it in the controller method

I have got trouble to send id from view to controler

#model IEnumerable<Evidencija.Models.Vozilo>
#{
ViewBag.Title = "PokreniIzvjestaj";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>PokreniIzvjestaj</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Vozilo</legend>
<p>
#Html.DropDownList("Vozila", Model.Select(p => new SelectListItem { Text = p.VoziloID.ToString(), Value = p.VoziloID.ToString() }), "Izaberi vozilo")
</p>
<input type="submit" value="Dodaj stavku" />
</fieldset>
}
I want to send id of table vozilo to controler with dropdownlist.
Controler accepts vozilo as a parameter but it is ollways zero.
How can I solve this without using viewmodel.
[HttpPost]
public ActionResult PokreniIzvjestaj(Vozilo v)
{
ReportClass rpt = new ReportClass();
rpt.FileName = Server.MapPath("~/Reports/Vozilo.rpt");
rpt.Load();
//ReportMethods.SetDBLogonForReport(rpt);
//ReportMethods.SetDBLogonForSubreports(rpt);
// rpt.VerifyDatabase();
rpt.SetParameterValue("#VoziloId",v.VoziloID);
Stream stream = null;
stream = rpt.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
return File(stream, "application/pdf", "Vozilo.pdf");
//PortableDocFormat--pdf format
//application/pdf -- vezan za pdf format, ako je drugi tip mjenja se u zavisnosti od izabranog
//naziv.pdf -- naziv dokumenta i izabrana ekstenzija
}
[HttpGet]
public ActionResult PokreniIzvjestaj()
{
var vozila = db.Voziloes.ToList();
return View(vozila);
}
There are two method from controler.
You currently binding your drop down to a property named Vozilo. A <select> post back single value (in your case the VoziloID or the selected option. Your POST method then tries to bind a complex object Vozilo to an int (assuming VoziloID is typeofint) which of course fails and the model isnull`. You could solve this changing the method to
[HttpPost]
public ActionResult PokreniIzvjestaj(int Vozilo)
The parameter Vozilo will now contain the value of the selected VoziloID.
However it not clear why you want to "solve this without using viewmodel" when using a view model is the correct approach
View model
public class VoziloVM
{
[Display(Name = "Vozilo")]
[Required(ErrorMessage = "Please select a Vozilo")]
public int? SelectedVozilo { get; set; }
public SelectList VoziloList { get; set; }
}
Controller
public ActionResult PokreniIzvjestaj()
{
var viziloList = db.Voziloes.Select(v => v.VoziloID);
VoziloVM model = new VoziloVM();
model.VoziloList = new SelectList(viziloList)
model.SelectedVozilo = // set a value here if you want a specific option selected
return View(model);
}
[HttpPost]
public ActionResult PokreniIzvjestaj(VoziloVM model)
{
// model.SelectedVozilo contains the value of the selected option
....
}
View
#model YourAssembly.VoziloVM>
....
#Html.LabelFor(m => m.SelectedVozilo)
#Html.DropDownListFor(m => m.SelectedVozilo, Model.VoziloList, "-Please select-")
#Html.ValidationMessageFor(m => m.SelectedVozilo)
....

NullReferenceException after POST

I've got a form that has a dropDownlist using the Model to fill the list, the view is rendered. The issue is that when i press the submit button, a null pointer exception for Model is thrown. I want to receive the value selected in the Post Action.
Here is my code:
Model:
public class BillViewModel
{
public List<SelectListItem> ClientList { get; set; }
public int SelectedClient { get; set; }
}
Controller Action:
public ActionResult Index()
{
var billRepo = new BillRepo();
var bill = new BillViewModel {ListProducts = billRepo.GetAllProducts()};
bill.ClientList = new List<SelectListItem>();
List<Client> allClientList = billRepo.GetAllClients();
foreach (Client client in allClientList)
{
var item = new SelectListItem() { Value = client.ClientId.ToString(), Text = client.Name };
bill.ClientList.Add(item);
}
ViewBag.ClientSelect = new SelectList(billRepo.GetAllClients(), "value", "text", bill.SelectedClient);
bill.SelectedClient = 1;
return View(bill);
}
[HttpPost]
public ActionResult Index(BillViewModel billViewModel)
{
return View();
}
View: this is where I get the null pointer exception in Model.ClientList
#using (Html.BeginForm())
{
#Html.DropDownListFor(item => item.SelectedClient, Model.ClientList, "Select Client")
<input type="submit" value="Aceptar"/>
}
In the [HttpPost] action method, you are invoking the View() method without any viewmodel. Therefore the Model property inside the view is null. The solution is simply to invoke View and passing in the BillViewModel.
Ex:
[HttpPost]
public ActionResult Index(BillViewModel billViewModel)
{
return View(billViewModel);
}
As the error is trying to tell you, Model.ClientList is null.
You need to initialize the model, just like you did in the GET action. (for example, by calling the same function)

How can I create a search functionality with partial view in asp.net mvc 4

I am using ASP.NET MVC 4 with entity framework model first.
In my "Masterpage.cshtml" I want to have a partial view which contains a textbox and a button.
The search is looking for the items title, if the text contains a items title it should display those items.
When a text is submitted the #renderbody() should show a view with the items.
My question is how can I do this in a good way? whats a good and easy approach?
So far I have done this:
Created a method in my repository that does the search function:
public List<News> Search(string query)
{
var queryz = db.News.Where(x => x.Title.Contains(query));
return queryz.ToList();
}
Now when it comes to my Searchcontroller im kinda lost how to do this. Beacuse one actionresult need to be the partialview that has a string query parameter and other one that contains a view that will display the items?
What I have done right now is having the whole process in same actionresult:
Repository rep = new Repository();
[HttpPost]
public ActionResult Search(string query)
{
var searchlist = rep.Search(query);
var model = new ItemViewModel()
{
NewsList = new List<NewsViewModel>()
};
foreach (var NewsItems in searchlist)
{
FillProductToModel(model, NewsItems);
}
return View(model);
}
private void FillProductToModel(ItemViewModel model, News news)
{
var productViewModel = new NewsViewModel
{
Description = news.Description,
NewsId = news.Id,
Title = news.Title,
link = news.Link,
Imageurl = news.Image,
PubDate = news.Date,
};
model.NewsList.Add(productViewModel);
}
any kind of help is appreciated alot!
You could use the following approach:
Index.cshtml
Have one DIV that calls the search controller action, and another that'll display the results.
<div id="search-form">
#Html.Action("Search", "Home"); // GET action in controller that displays form
</div>
<div id="search-results">
</div>
_SearchFormPartial.cshtml
Create a partial view that'll contain the search form. You can use Ajax.BeginForm so when a user searches the results will be displayed in the search-results DIV in Index.cshtml by AJAX. UpdateTargetId specifies that we want to pass the results of the search to the search-results DIV.
#using (Ajax.BeginForm("Search", "Home", FormMethod.Post,
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
UpdateTargetId = "search-results"
}))
{
<div>
#Html.TextBox("query")
<input type="submit" value="Search" />
</div>
}
Controller
In your controller you'll need one action to display the form (partial view above) and another to process the search query and retun another partial view that'll display the results:
[HttpGet]
public ActionResult Search()
{
return PartialView("_SearchFormPartial");
}
[HttpPost]
public ActionResult Search(string query)
{
if(query != null)
{
try
{
var searchlist = rep.Search(query);
var model = new ItemViewModel()
{
NewsList = new List<NewsViewModel>()
};
return PartialView("_SearchResultsPartial", model);
}
catch (Exception e)
{
// handle exception
}
}
return PartialView("Error");
}
_SearchResultsPartial.cshtml
This partial will display the results. It's strongly typed taking in an ItemViewModel.
#model Namespace.ViewModels.ItemViewModel
#if (Model.SearchResults.Count == 0)
{
<h3 class="text-error">No items matched your search query!</h3>
}
else
{
foreach (var result in Model.NewsList)
{
// display search results
}
}
If your _SearchResultsPartial.cshtml is not inserted into the DOM element of given ID, you should add a script: query.unobtrusive-ajax.js
It fixed the MattSull's solution in my case

on asp.net mvc 3 using the razor engine, what's the best practice to pass data between multiple views?

first of all, sorry for my english
I am new to ASP.NET MVC and was trying to develop a simple web application using the Razor Engine
so I have this view called Extract, which accepts an url as input:
#using (Html.BeginForm("Begin", "Rss"))
{
#Html.LabelFor(m => m.Url) #Html.TextBoxFor(m => m.Url)
<button>Extrair</button>
}
when submited, it will send the url to my controller:
public ActionResult Begin(ExtractModel m)
{
if (ModelState.IsValid)
{
var extractedData = ExtractorService.Extract(m.Url);
if (extractedData != null)
{
TempData["extractedData"] = extractedData;
return RedirectToAction("Extracted", extractedData);
}
}
return View();
}
then a new view called Extracted will show all the links extracted from the rss passed:
public ActionResult Extracted(ExtractedModel m)
{
if (TempData["extractedData"] != null)
{
ViewData["extractedData"] = TempData["extractedData"];
return View(ViewData["extractedData"] as ExtractedModel);
}
else
{
return RedirectToAction("Extract");
}
}
-
#using (Html.BeginForm())
{
foreach (var data in Model.Data)
{
<ul>
<li>#data.Link</li>
</ul>
}
<button>Converter</button>
}
bottom line what I want to ask is: how do I get the ViewData["extractedData"] which I set when loading this View so I can pass it back to the controller and parse all the info inside of it? because when I click on the button Converter my ViewData is empty and I can't process anything without it =\
I wouldn't use TempData for passing complex objects between the views. I would also get rid of ViewData.
Then I would rather have the controller action rendering the view fetch whatever information it needs:
public class RssController: Controller
{
public ActionResult Extract()
{
var model = new ExtractModel();
return View(model);
}
[HttpPost]
public ActionResult Begin(string url)
{
if (ModelState.IsValid)
{
return RedirectToAction("Extracted", new { url = url });
}
return View();
}
}
have the corresponding view which allows for entering the url (~/Views/Rss/Extract.cshtml):
#model AppName.Models.ExtractModel
#using (Html.BeginForm("Begin", "Rss"))
{
#Html.LabelFor(m => m.Url)
#Html.TextBoxFor(m => m.Url)
<input type="submit" value="Extrair" />
}
and in the other action you are redirecting to:
public ActionResult Extracted(string url)
{
var extractedData = ExtractorService.Extract(url);
if (extractedData != null)
{
return View(extractedData);
}
return RedirectToAction("Extract");
}

Categories