Issue with mvc, partial view dispaying - asp.net-mvc

I have a question about partial view. I want to display in header Login form which i created. In HomeController I have 2 actions: one is Login and other is Login with httppost method.
In partial view (_Layout.cshtml) I have a code - only send footer div:
<td style="text-align:center">
<h3>Bookstore</h3>
#Html.Partial("_LoginPartial")
</td>
In Login view I have:
#using(Html.BeginForm("Login", "Home", FormMethod.Post)){
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<table>
<tr>
<td>#Html.LabelFor(a=>a.Username)</td>
<td>#Html.TextBoxFor(a=>a.Username)</td>
<td>#Html.ValidationMessageFor(a=>a.Username)</td>
</tr>
<tr>
<td>#Html.LabelFor(a=>a.Password)</td>
<td>#Html.PasswordFor(a=>a.Password)</td>
<td>#Html.ValidationMessageFor(a=>a.Password)</td>
</tr>
<tr>
<td>
<input type="submit" value="Login" />
</td>
</tr>
</table>}
Controller
public ActionResult Login()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(Users u)
{
if (ModelState.IsValid) {
using (DatabaseLoginEntities dl = new DatabaseLoginEntities()) {
var v = dl.Users.Where(a => a.Username.Equals(u.Username) && a.Password.Equals(u.Password)).FirstOrDefault();
if (v != null) {
Session["LogedUserId"] = v.UserAccountID.ToString();
Session["LogedUserFullName"] = v.FullName.ToString();
return RedirectToAction("AfterLogin");
}
}
}
return PartialView("_LoginPartial", u);
}
When press Login button, mvc switches me to separate page in which Login form is shown. I don't want that to happen. It must stay in header. Functionality is ok but I have issue how to show that only in header. Has anyone have idea where I'm wrong?

you must use ajax
#using (Ajax.BeginForm("Login", "Home",
new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.Replace
,
UpdateTargetId = "div_id"
}
)){
<table>
<tr>
<td>#Html.LabelFor(a=>a.Username)</td>
<td>#Html.TextBoxFor(a=>a.Username)</td>
<td>#Html.ValidationMessageFor(a=>a.Username)</td>
</tr>
<tr>
<td>#Html.LabelFor(a=>a.Password)</td>
<td>#Html.PasswordFor(a=>a.Password)</td>
<td>#Html.ValidationMessageFor(a=>a.Password)</td>
</tr>
<tr>
<td>
<input type="submit" value="Login" />
</td>
</tr>
</table>
}

Related

HTML Helpers not working after sending blank value in textbox

I am banging my head for the last 3 hours and I don't know what is wrong.
My question is, Why HTML helpers are not working when I submit a blank value in ProjectCode. Below are my View and Controller?
View:
#using Models;
#model LoginViewModel
#{
ViewBag.Title = "Login";
Layout = "~/Views/_MainTheme.cshtml";
}
#using (Html.BeginForm("Search", "Home", FormMethod.Get))
{
#Html.TextBoxFor(x => x.ProjectCode)
<input type="submit" name="Search" value="Search" />
<br />
#Html.ActionLink("Create", "Details", "NewSurvey")
<br />
<div style="display:#(Model.SurveyList.Surveys.Count > 0 ? "block" : "none");">
<div>#Model.SurveyListTableHeader</div>
<table border="1">
<thead>
<tr>
<td>Project Code</td>
<td>Project Name</td>
</thead>
#foreach (var survey in Model.SurveyList.Surveys)
{
<tr>
<td>#survey.Value.ProjectCode</td>
<td>#survey.Value.ProjectName</td>
}
</table>
</div>
}
Controller:
public ActionResult Login()
{
Session["CurrentPage"] = ePages.Login;
LoginViewModel login = new LoginViewModel();
login.SurveyList = BusinessOperations.GetExistingUserSurveys("mp12672", ref ScreenMessages._Message, ref ScreenMessages._MessageStateID);
login.SurveyListTableHeader = "Recently Accessed Surveys";
return View("Login", login);
}
public ActionResult Search(LoginViewModel login)
{
Session["CurrentPage"] = ePages.Login;
login.SurveyList = BusinessOperations.GetProjectSurveys(login.ProjectCode, ref ScreenMessages._Message, ref ScreenMessages._MessageStateID);
login.SurveyListTableHeader = "Surveys matching your search";
return View("Login", login);
}
public ActionResult Resume(string SurveyKey)
{
Session["SurveyKey"] = SurveyKey;
return RedirectToAction("Introduction", "OMS");
}
}
The exception I get is:
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
on the below line
#Html.ActionLink("Create", "Details", "NewSurvey")

ASP.NET MVC CheckBox List sending always null

I want to create a table with items and checkboxes to select these items. I am including these checkboxes in a list but this list is always returning null. Thank you very much for your help.
Controller:
public ActionResult Index()
{
var expenseTypesView = new ViewExpenseTypesAndSelection
{
ExpensesTypes = _context.ExpenseType.ToList(),
};
return View(expenseTypesView);
}
[HttpPost]
public ActionResult SelectExpensesTypes( ViewExpenseTypesAndSelection SelectedExpenses)
{
var entry = new userSpecificExpenses();
var i = 0;
foreach (var item in SelectedExpenses.SelectedExpenses)
{
if(item)
{
entry.expenseTypeId = i;
entry.UtilisateurId= User.Identity.GetUserId();
_context.UserspecificExpenses.Add(entry);
_context.SaveChanges();
}
i++;
}
return View();
}
View:
#model MBT.ViewModels.ViewExpenseTypesAndSelection
....
#using (Html.BeginForm("SelectExpensesTypes", "ExpenseTypes"))
{
<table class="table table-bordered table-hover">
<thead>
<tr>
<th class="text-center">Expense</th>
<th class="text-center">Include</th>
</tr>
</thead>
<tbody>
#{
for (int i = 0; i < Model.ExpensesTypes.Count; i++)
{
<tr>
<td>
<div class="checkbox">
#Model.ExpensesTypes[i].Type
</div>
</td>
<td>
<div class="checkbox">
#Html.CheckBoxFor(m => m.SelectedExpenses[i])
</div>
</td>
</tr>
}
}
</tbody>
</table>
<button type="submit" class="btn btn-primary">Submit</button>
}
You sending ViewExpenseTypesAndSelection almost null just with ExpensesTypes and then post it back to your post method. It means you send null and receive null.
So what is wrong with that?

How to add Edit, Delete and Search functionality in single view in MVC?

I'm new to MVC.
on MSDN i've studied that there should be folder in view with the same name of controller. For every Action Method in the controller we have to create a View in the same folder.
I'm creating a test application in which:
I have a homeController with an Index ActionMethod. Corresponding to it i have a View in View/home/Index, which simply show the listing of the employees.
I know i can add a [HTTP POST] Index ActionMethod in the homeController.
But i want to add the Delete and Search functionality on the view. So that a user can search the employees with there name and can delete an employee on the same page.
I don't know how can i move ahead for this functionality.
Still i'm using this code.
homeController
public ActionResult Index()
{
ViewBag.text = "Records Listing";
var q = from p in objEmp.tbemployees select p;
return View(q);
}
Index.cshtml
#model IEnumerable<MvcApplication6.Models.tbemployee>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>#ViewBag.text</h1>
<table style="font-size:15px;">
<tr>
<th>
Name
</th>
<th>
Address
</th>
<th>
Sallary
</th>
</tr>
#foreach (var item in Model)
{
<tr >
<td style="padding:7px;">
#Html.DisplayFor(mm => item.ename)
</td>
<td style="padding:7px;">
#Html.DisplayFor(mm => item.eadd)
</td>
<td style="padding:7px;">
#Html.DisplayFor(mm => item.esal)
</td>
<td style="padding:7px; color:Blue; text-decoration:underline;">
#Html.ActionLink("Edit", "Edit", new { id = item.empno })
</td>
</tr>
}
</table>
Thanks.
For the Delete you could add a column in the table that will invoke a controller action and pass it the current record id:
<tr>
<td style="padding:7px;">
#Html.DisplayFor(mm => item.ename)
</td>
<td style="padding:7px;">
#Html.DisplayFor(mm => item.eadd)
</td>
<td style="padding:7px;">
#Html.DisplayFor(mm => item.esal)
</td>
<td style="padding:7px; color:Blue; text-decoration:underline;">
#Html.ActionLink("Delete", "Delete", new { id = item.empno })
#Html.ActionLink("Edit", "Edit", new { id = item.empno })
</td>
</tr>
and your Delete action:
public ActionResult Delete(int id)
{
... use the passed id to delete the record from the database
return RedirectToAction("Index");
}
for the Edit functionality you could have a controller action that will fetch the record and render a view that will allow for editing:
public ActionResult Edit(int id)
{
var employee = objEmp.tbemployees.FirstOrDefault(x => x.Id == id);
if (employee == null)
{
// no employee with the specified id was found
return new HttpNotFound();
}
return View(employee);
}
and then you could have a corresponding ~/Views/Home/Edit.cshtml view:
#model Employee
#using (Html.BeginForm())
{
<div>
#Html.LabelFor(x => x.ename)
#Html.EditorFor(x => x.ename)
</div>
<div>
#Html.LabelFor(x => x.eadd)
#Html.EditorFor(x => x.eadd)
</div>
...
<button type="submit">Save</button>
}
and of course a corresponding action to update the record when this form is submitted:
[HttpPost]
public ActionResult Edit(Employee employee)
{
... update the employee record
return RedirectToAction("Index");
}
You can add and implement a Delete action method in your controller. Then in your view, call #Html.ActionLink("Delete", "Delete", new { id = item.empno }). This will return a hyperlink which links to your Delete method in the controller.

Asp.MVC RenderAction for part of the page doesn't work as I expect

Ok I mess my page really bad and I need good help here.
I have a login page with Login and Register partial views.
RegisterView has it's own ViewModel class and it makes me problem.
I render Register partial view by using "RenderAction" helper.
Biggest problem is validation. When I don't enter anything in register fields and click submit register partial view is not updated inside it's parrent LoginView but return me only RegisterView. In other words my validation works but not where I want it to work.
LogOn.cshtml (this one contains register partial view)
<div id="regstrationForm">
#{Html.RenderAction("RegisterUser", "Account");}
</div>
Register (Partial View)
#using (#Ajax.BeginForm("RegisterUser", "Account", new AjaxOptions { UpdateTargetId = "reg" }))
{
<table id="reg">
...
<tr>
<td>
#Html.TextBoxFor(u => u.Username, new { #class = "registrationTextFields", placeholder = "Email" })
</td>
</tr>
<tr>
<td>
#Html.TextBoxFor(p => p.Password, new { #class = "registrationTextFields", placeholder = "Password" })
</td>
</tr>
<tr>
<td align="right">
<input class="signUpButton" type="submit" value="Sign up" />
</td>
</tr>
<tr>
<td>
#Html.ValidationMessage("myerrorsummary")
</td>
</tr>
</table>
This is HttpPost controller method when user click on sign up button.
Here I tried to return "PartialView()" and it turns my input fields to red css style but not display validation information bellow those fields.
[HttpPost]
public ActionResult RegisterUser(RegisterViewModel logOnViewModel)
{
if (ModelState.IsValid)
{
MembershipCreateStatus result;
try
{
...
}
else
{
ModelState.AddModelError("myerrorsummary", "The input is not valid");
ViewBag.CountryList = countryRepository.GetAllCountries();
ViewBag.CityList = cityRepository.GetAllCitiesByCountryId(1);
return View(logOnViewModel);
}
}
I suspect that you forgot to include the following script in your main view:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
This is what makes Html helpers such as Ajax.BeginForm and Ajax.ActionLink to perform AJAX requests instead of normal.
You might also take a look at the following article which explains in more details about how those helpers work in ASP.NET MVC 3.

delete rows of table on checking of checkboxes

I have table containing data . In every row there is a checkbox plus a checkbox to select all checkbox at the headers.
Upon checking this checkboxes,corresponoding rows are to be deleted from database table.Plus,on chiecking the checkbox at the header,all rows will be deleted from the database table.How can i achieve this asp.net mvc.
As always start with a model:
public class ProductViewModel
{
public int Id { get; set; }
public string Name { get; set; }
}
Then a controller:
public class HomeController : Controller
{
// TODO: Fetch this from a repository
private static List<ProductViewModel> _products = new List<ProductViewModel>
{
new ProductViewModel { Id = 1, Name = "Product 1" },
new ProductViewModel { Id = 2, Name = "Product 2" },
new ProductViewModel { Id = 3, Name = "Product 3" },
new ProductViewModel { Id = 4, Name = "Product 4" },
new ProductViewModel { Id = 5, Name = "Product 5" },
};
public ActionResult Index()
{
return View(_products);
}
[HttpPost]
public ActionResult Delete(IEnumerable<int> productIdsToDelete)
{
// TODO: Perform the delete from a repository
_products.RemoveAll(p => productIdsToDelete.Contains(p.Id));
return RedirectToAction("index");
}
}
And finally the Index.aspx view:
<% using (Html.BeginForm("delete", "home", FormMethod.Post)) { %>
<table>
<thead>
<tr>
<th>Name</th>
<th>Select</th>
</tr>
</thead>
<tbody>
<%= Html.EditorForModel()%>
</tbody>
</table>
<input type="submit" value="Delete selected products" />
<% } %>
And the product editor template (~/Views/Home/EditorTemplates/ProductViewModel.ascx):
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ToDD.Controllers.ProductViewModel>" %>
<tr>
<td>
<%: Model.Name %>
</td>
<td>
<input type="checkbox" name="productIdsToDelete" value="<%: Model.Id %>" />
</td>
</tr>
I would use AJAX. On changing the checked state, I would submit a request to delete all the selected IDs and refresh the table data.
Use jQuery, some other javascript library, or just hand code an AJAX request on check of checkbox. Then alter the DOM on success.
Using jQuery you could do something like:
<table>
<tr>
<td><input type="checkbox" class="check" id="1" /></td>
</tr>
<tr>
<td><input type="checkbox" class="check" id="2" /></td>
</tr>
<tr>
<td><input type="checkbox" class="check" id="3" /></td>
</tr>
</table>
$('.check').click(function() {
var tableRow = $(this).parent().parent();
var id = $(this).attr('id');
$.ajax({
url: 'http://www.YOURDOMAIN.com/Controller/Action/' + id,
success: function(data) {
$(tableRow).remove();
}
});
)};
This is very basic implementation, you could dress it up with some animation in the removal of the row. You also need to pass data and return data with some error handling. Check out here for a jQuery AJAX tutorial.

Resources