How to get the Partial View object on form submit - asp.net-mvc

How to get the Partial View object on form submit
Main View:
#model CreateCampaignModel
....
#using (Html.BeginForm("SubmitForm", "Campaign", FormMethod.Post))
{
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse2">Step 2: Creative*</a>
</h4>
<a style="padding-left:90%;" id="lnkEdit">Edit</a>
</div>
#Html.EditorFor(m => Model.campaignCreativeModelList[0])
#foreach (var m in Model.campaignCreativeModelList)
{
<div id="collapse2" class="panel-collapse collapse">
#Html.Partial("~/Views/Campaign/_Creative.cshtml", m)
</div>
}
</div>
}
Creative Partial View:
<div class="panel-body">
<div class="form-group">
#Html.Partial("~/Views/Shared/_ImageVideoUploadView.cshtml", Model.socialJobMediaModel)
</div>
<div class="col-md-10">
<div class="editor-field">
<input type="submit" name="Save Group" value="Review and Submit" class="btn btn-primary" />
</div>
</div>
</div>
My Controller Action:
[HttpPost]
public ActionResult SubmitForm(CreateCampaignModel createCampaignModel)
{
return (View(BindCampaignModel()));
}
I want to return the campaignCreativeModel object to the controller with all the collections of partial views inside partial views.
My Main Model:
public class CreateCampaignModel
{
public List<CampaignCreativeModel> campaignCreativeModelList { get; set; }
public List<ClientAccountCampaignBundlesModel> clientAccountCampaignBundlesModelList { get; set; }
public List<CampaignBundleSchedulesModel> campaignBundleSchedulesModelList { get; set; }
public List<CampaignConfigurationModel> campaignConfigurationModelList { get; set; }
public CampaignConfigurationModel campaignConfigurationModel { get; set; }
}
My model have all the collections related to partial views in the main view.
Screenshot:

I haven't gone through your code completely
[HttpPost]
public ActionResult SubmitForm(list<CreateCampaignModel> createCampaignModelList)
{
return (View(BindCampaignModel()));
}
this is the idea, you can get collection,if you are building the partial view from the model, I haven't tested the code..

Related

Why does EF insert the same Guid Ids in different fileds?

I've a Page entity dependent on Investor entity as investor creates a page:
public class Page
{
[Required, DatabaseGenerated(DatabaseGeneratedOption.Identity), Key]
public Guid Id { get; set; }
[Required(ErrorMessage = "Describe the idea of your blog")]
public string Description { get; set; }
[Display(Name = "Тags")]
[Required(ErrorMessage = "Let people know what content you're going to share")]
public ICollection<Investor> Subscribers { get; set; }
public Guid AuthorId { get; set; }
public Investor Author { get; set; }
}
That's what in my dbContext:
modelBuilder.Entity<Page>()
.HasOne(b => b.Author)
.WithOne(u=> u.Page)
.HasForeignKey<Page>(b => b.AuthorId)
.OnDelete(DeleteBehavior.Restrict);
Here's the controller for creating a Page:
public class PageController : Controller
{
private readonly DataManager _dataManager;
private readonly UserManager<ApplicationUser> _userManager;
public PageController(UserManager<ApplicationUser> userManager, DataManager dataManager)
{
_userManager = userManager;
_dataManager = dataManager;
}
public IActionResult Create(Guid Id)
{
var investor = _dataManager.Investors.GetInvestorById(Id);
if (investor.Page != null)
{
return RedirectToPage("/Account/ProfileCheck", new { Id = investor.User.Id, area = "Identity"});
}
var page = new Page();
return View(page);
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Page page)
{
if (ModelState["Description"].Errors.Count() == 0)
{
var currentUserId = _userManager.GetUserId(HttpContext.User);
var investor = _dataManager.Investors.GetInvestorByUserId(currentUserId);
page.Author = investor;
_dataManager.Pages.SavePage(page);
return RedirectToPage("/Account/ProfileCheck", new { Id = investor.User.Id, area = "Identity" });
}
return View(page);
}
}
However, In HttpPost Action that page has an Id and this Id equals to author's Id who created it.
This's the view for Create action
#model FinicWebApp.Domain.Entitites.Page
<form method="post" asp-action="Create">
<div class="border p-3">
<div asp-validation-summary="ModelOnly" class="text-danger" ></div>
<div class="form-group row">
<h2 class="text-black-50 pl-3">Create Page</h2>
</div>
<div class="row">
<div class="col-12">
<div class="form-group row">
<div class="col-6">
<label asp-for="Description"></label>
</div>
</div>
<div class="form-group row">
<div class="col-4">
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="col-8 text-center row">
<div class="col">
<input type="submit" class="btn btn-info w-75" value="Create"/>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
In my db all the pages' ids equal to investors' ids who created them. But I need pages' ids to be different. How can I get it?

How Can I Get ViewData in PartialView in Razor Pages

I'm Using Razor Pages For my App, in one part of my app I've used a partial view here is my codes;
public class Permission
{
[Key]
public int PermissionId { get; set; }
public string PermissionTitle { get; set; }
public int? ParentID { get; set; }
}
public class IndexModel : PageModel
{
public PartialViewResult OnGetCreateRole()
{
var ListPermission = permissionService.AllPermission();
return new PartialViewResult()
{
ViewName = "_PCreateRole", // partial's name
ViewData = new ViewDataDictionary<List<Permission>>(ViewData,
ListPermission)
};
}
}
ViewData is a List of Permission class and i've sent ViewData to partial but i dont know how to get ViewData, also my partial use another model, below is my partial:
#model ToMVC.DataLayer.Entities.User.Role
<div class="row">
<div class="col-md-12">
<form asp-page="CreateRole" method="post">
<div class="form-group">
<label class="control-label">Title</label>
<input asp-for="RoleTitle" class="form-control"/>
<p><span class="text-danger" asp-validation-for="RoleTitle"></span></p>
</div>
<div class="form-group">
<input type="submit" value="submit" class="btn btn-primary" />
</div>
//this part needs ViewData
#foreach (var item in ViewData)
{
}
</form>
</div>
</div>
I want to use ViewData in Foreach loop.
A better solution than ViewData would be to simply make a new ViewModel class containing all the information you need for a view.
public class UserRoleAndPermissions{
public UserRoleAndPermissions(){
Permissions = new List<Permissions>();
}
public List<Permission> Permissions {get;set;}
public ToMVC.DataLayer.Entities.User.Role Role {get;set;}
}
And your view
//check your namespace here - this is just an example
#model ToMVC.DataLayer.UserRoleAndPermissions
<div class="row">
<div class="col-md-12">
<form asp-page="CreateRole" method="post">
<div class="form-group">
<label class="control-label">Title</label>
<input asp-for="RoleTitle" class="form-control"/>
<p><span class="text-danger" asp-validation-for="RoleTitle"></span></p>
</div>
<div class="form-group">
<input type="submit" value="submit" class="btn btn-primary" />
</div>
#foreach (var item in Model.Permissions)
{
}
</form>
</div>
</div>

Adding users to a list MVC

I have a form in which the user is supposed to enter Name and Wage and click a button Add. When the button "Add" is clicked, that user is supposed to be displayed on a list.
This is how I tried it.
Controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TimeIsMoney.Models;
namespace TimeIsMoney.Controllers
{
public class HomeController : Controller
{
List<UserModel> users = new List<UserModel>();
public ActionResult Index(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
public ActionResult AddUser(UserModel user)
{
users.Add(user);
return View(users);
}
}
}
View:
#model TimeIsMoney.Models.LoginModel
#{
}
#functions{
public string GetAntiForgeryToken()
{
string cookieToken, formToken;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
return cookieToken + ":" + formToken;
}
}
<div id="main-content" class="col-md-8 col-md-offset-2">
<div class="col-md-12 row">
<h1>Time is money my friend!</h1>
</div>
<div class="col-md-12 row">
<h2>1000kr</h2>
</div>
<div class="col-md-12 row">
<button class="btn" onclick="start()">Start</button>
<button class="btn" onclick="reset()">Reset</button>
</div>
<div class="col-md-12 row">
<form >
<input type="text" placeholder="Name" />
<input type="number" placeholder="Hourly wage" />
<input type="submit" value="Add" onclick="AddUser()" />
</form>
</div>
<div class="col-md-12 row">
<div class="col-md-3 col-md-offset-1">
<label>Name:</label>
<ul>
<li>Dave</li>
<li>Pete</li>
</ul>
</div>
<div class="col-md-4">
<label>Wage:</label>
<ul>
<li>500kr/h</li>
<li>500kr/h</li>
</ul>
</div>
</div>
<br />
<br />
</div>
Model:
namespace TimeIsMoney.Models
{
public class UserModel
{
[Required]
[DataType(DataType.Text)]
[DisplayName("Username")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Text)]
[DisplayName("Wage")]
public string Wage { get; set; }
}
}
Am I on the right path?
How can I move on from here?
UPDATE:
public ActionResult AddUser(UserModel user)
{
var list = Session["myUsers"] as List<UserModel>;
list.Add(user);
return View(list);
}
You're mostly on the right path excluding way you're trying to store your users list.
Since ASP.NET MVC controller instance is created for every request and disposed after view is rendered and passed to the browser - it will be new controller holding new List<UserModel> created on every request.
So you have to store it somewhere else (session variables, file on server's disk, database and so on). Usually database is best choice for this.
In the case you want to store it in session variable, you should add something like this into Global.asax:
protected void Session_Start(object sender, EventArgs e)
{
Session["myUsers"] = new List<UserModel>();
}
and then in your controller's methods you will be able to access this list as
var list = Session["myUsers"] as List<UserModel>;

How to keep track of things in asp.net.mvc?

I'm developing a small web application and I need help tracking states.
This application ask few questions to a user in a random manner (one at a time). But, to do so, I need to know which question already been answered (so I don't repeat any questions) and if the user got it right or not.
I need to know if the user got the last question right because, if he awnsers wrong, the application will ask a random question from a different list.
To do so, I created this class "state" in the controller which is supposed to keep track of things.
public class state
{
public string via { get; set; }
public string previousQuestionList { get; set; }
public string currentQuestionList { get; set; }
public string leftButton { get; set; }
public string rightButton { get; set; }
public List<Question> previousQuestions { get; set; }
public Question currentQuestion { get; set; }
public bool lastAnswer { get; set; }
}
So, when the user enters the page for the first time, the controller send a default information to the view and it constructs the page.
public ActionResult Index()
{
state currentState = new state();
currentState.currentQuestion = new Question();
currentState.currentQuestion.description = "Qual a via do seu cartão?";
currentState.currentQuestion.aplicabilidade = true;
currentState.leftButton = "1a Via";
currentState.rightButton = "2a Via";
return View(currentState);
}
And the view looks like this:
The html code is something like this:
#{
ViewBag.Title = "Sistema de Script de Desbloqueio";
}
#model Sistema_de_Script_de_Desbloqueio.Controllers.HomeController.state
<div class="jumbotron">
<h1>#Model.currentQuestion.description</h1>
</div>
<form name="Formulário" action="~/Views/Home/Index.cshtml" method="post">
#if (Model.currentQuestion.aplicabilidade == true)
{
<div class="row">
<div class="col-md-6">
<div class="btn btn-primary btn-group-justified" role="group"><h2>#Model.leftButton</h2></div>
</div>
<div class="col-md-6">
<div class="btn btn-warning btn-group-justified" role="group"><h2>#Model.rightButton</h2></div>
</div>
</div>
}
else
{
<div class="row">
<div class="col-md-4">
<div class="btn btn-primary btn-group-justified" role="group"><h2>#Model.leftButton</h2></div>
</div>
<div class="col-md-4">
<div class="btn btn-warning btn-group-justified" role="group"><h2>#Model.rightButton</h2></div>
</div>
<div class="col-md-4">
<div class="btn btn-default btn-group-justified" role="group"><h2>N/A</h2></div>
</div>
</div>
}
</form>
My idea is that the user press one of the buttons and send the object of the class "state" (model) back along with the information of which button was pressed to the controller.
Is it possible?
I used the tip from "elolos" and used "Session" to maintain the date and worked just fine.
public ActionResult Index()
{
state currentState = new state();
//Some code here
Session["currentState"] = currentState
return View(currentState);
}
And then in the "Post" method I retrieved the information from "currentState"
[HttpPost]
public ActionResult Index(string lastButton)
{
state currentState = Session["currentState"] as state;
//Some code here
return View(currentState);
}
Thank you.
Easiest way would be to perform simple Postback or AJAX POST from view you are creating.
Add property for last button clicked to model:
public string LastClickedButton { get; set; }
Then add ActionResult to POST to:
public ActionResult IndexPost(state postedState)
{
//Do stuff.
}
And perform POST from view:
#{
ViewBag.Title = "Sistema de Script de Desbloqueio";
}
#model Sistema_de_Script_de_Desbloqueio.Controllers.HomeController.state
<div class="jumbotron">
<h1>#Model.currentQuestion.description</h1>
</div>
<form name="Formulário" action="~/Views/Home/Index.cshtml" method="post">
#if (Model.currentQuestion.aplicabilidade == true)
{
<div class="row">
#using (#Html.BeginForm("IndexPost", "Home"))
{
<div class="col-md-6">
<div class="btn btn-primary btn-group-justified" role="group"><h2>#Model.leftButton</h2></div>
</div>
#Html.Hidden("LastClickedButton", #Model.leftButton);
}
#using (#Html.BeginForm("IndexPost", "Home"))
{
<div class="col-md-6">
<button class="btn btn-warning btn-group-justified" role="group" type="submit"><h2>#Model.rightButton</h2></div>
</button>
#Html.Hidden("LastClickedButton", #Model.rightButton);
}
</div>
}
else
{
<div class="row">
<div class="col-md-4">
<button class="btn btn-primary btn-group-justified" role="group" type="submit"><h2>#Model.leftButton</h2></button>
</div>
<div class="col-md-4">
<div class="btn btn-warning btn-group-justified" role="group"><h2>#Model.rightButton</h2></div>
</div>
<div class="col-md-4">
<div class="btn btn-default btn-group-justified" role="group"><h2>N/A</h2></div>
</div>
</div>
}
</form>
Downright of this is that you need to send all the information you received, so many redundant #Html.Hidden/#Html.HiddenFor will be produced.
Another way round this is you can change Controller action to:
public ActionResult IndexPost(state postedState, string clickedButton)
{
//Do anything you need with clickedButton
}
And post clickedButton via route:
#using (#Html.BeginForm("IndexPost", "Home", new { clickedButton = #Model.rightButton }))
{
<div class="col-md-6">
<button class="btn btn-warning btn-group-justified" role="group" type="submit"><h2>#Model.rightButton</h2></div>
</button>
}

After submit a form in a Area not displayed none of validation message?

I have a area and at this area i have a PostController, and a action with Add name for GET method and a action with Add name for POST method,after submit form i add error to modelstate BUT after postback,not displayed none of validation message and staus code is:301 Moved Permanently !!!
my viewmodel:
public class NewPostViewModel
{
[Required(ErrorMessage = "Please enter title.")]
public string Title { get; set; }
[AllowHtml]
[Required(ErrorMessage = "Please enter article content.")]
public string Content { get; set; }
[Required(ErrorMessage = "Please enter a tag.")]
public string Tags { get; set; }
public bool PublishNow { get; set; }
public string PublishDate { get; set; }
public string PublishTime { get; set; }
}
my view:
#model Soleimanzadeh.Models.ViewModels.NewPostViewModel
#{
ViewBag.Title = "Add";
Layout = MVC.Admin.Shared.Views.BaseLayout;
}
#using (Html.BeginForm(MVC.Admin.Post.Add(), FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(false, null, new { #class = "alert" })
<div class="row-fluid">
<div class="span9">
<div class="row-fluid">
<div class="span8">
#Html.TextBoxFor(np => np.Title, new { #class = "span12", placeholder = "Title" })
#Html.ValidationMessageFor(model=>model.Title)
</div>
</div>
<div class="row-fluid">
<div class="span12">
#Html.TextAreaFor(np => np.Content)
#Html.ValidationMessageFor(model=>model.Content)
</div>
</div>
</div>
<div class="span3">
<div class="row-fluid">
<div class="post-options-container">
<div class="header">
Tags
</div>
<div class="content">
<input type="text" placeholder="tags" class="tagManager" style="width: 100px;" />
</div>
</div>
</div>
<div class="row-fluid">
<div class="post-options-container">
<div class="header">
Status
</div>
<div class="content">
<label class="checkbox">
#Html.CheckBoxFor(np => np.PublishNow)
Publish Now?
</label>
<div>
Publish Date:
#Html.TextBoxFor(np => np.PublishDate, new { #class = "calcInput" })
</div>
<div>
Publish Time:
#Html.TextBoxFor(np => np.PublishTime, new { #class = "timeInput" })
</div>
<div>
<input type="submit" value="Save"/>
</div>
</div>
</div>
</div>
</div>
</div>
}
#*some scripts here*#
my controller:
public partial class PostController : Controller
{
public virtual ActionResult Add()
{
var newPost = new NewPostViewModel();
return View(MVC.Admin.Post.Views.Add, newPost);
}
[HttpPost]
[ValidateAntiForgeryToken]
public virtual ActionResult Add(NewPostViewModel post)
{
ModelState.AddModelError("Content","Wrong");
return this.View(MVC.Admin.Post.Views.Add, post);
}
}
Also i use redactor html editor for Content.
Solution:
i use http://lowercaseroutesmvc.codeplex.com/ for convert urls to lowercase,but i not enabled this tool in area section and page redirectd after submit form.

Resources