MVC 3 Razor - How to handle success/error messages - c#

I am using MVC3 for a new project and I am able to pass the values from my model to my DAL and successfully submit data to the database. Being new to MVC I am not sure how to handle success and error messages.
What I want to do is give the user some feedback after the form is submitted and I don't know if I am meant to create a new controller for this or reuse my current controller but write some logic in the view to hide the form and show the message.
ActionResult CreateUser is the form and ActionResult CreateUser with httppost handles form submission
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using UserManager.Models;
namespace UserManager.Controllers
{
public class UserManagerController : Controller
{
//
// GET: /UserManager/
public ActionResult Index()
{
try
{
var data = new UserManager.Models.UserManagerTestEntities();
return View(data.vw_UserManager_Model_Add_Users.ToList());
}
catch (Exception ex)
{
return View(ViewBag);
}
}
public ActionResult LookUpGroupName(string q, int limit)
{
//TODO: Map list to autocomplete textbox control
DAL d = new DAL();
List<string> groups = d.groups();
var GroupValue = groups
.Where(x => x.Contains(q))
.OrderBy(x => x)
.Take(limit)
.Select(r => new { group = r });
// Return the result set as JSON
return Json(GroupValue, JsonRequestBehavior.AllowGet);
}
public ActionResult CreateUser()
{
//var data = new UserManager.Models.UserManagerTestEntities();
ViewBag.Message = "Create New User";
return View();
}
[HttpPost]
public ActionResult CreateUser(vw_UserManager_Model_Add_Users newUser)
{
try
{
if (ModelState.IsValid)
{
//var data = new UserManager.Models.UserManagerTestEntities();
// Pass model to Data Layer
List<string> outcome = UserManager.DAL.CreateUser(newUser);
//data.SaveChanges();
}
return View();
}
catch (Exception ex)
{
return View(ex.ToString());
}
}
}
}
My DAL
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Data;
using System.Configuration;
using UserManager.Models;
using System.Security.Cryptography;
using System.Web.Security;
namespace UserManager
{
public class DAL
{
#region hashingpassword
private static string CreateSalt(int size)
{
// Generate a cryptographic random number.
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] buff = new byte[size];
rng.GetBytes(buff);
// Return a Base64 string representation of the random number.
return Convert.ToBase64String(buff);
}
private static string CreatePasswordHash(string pwd, string salt)
{
string saltAndPwd = string.Concat(pwd, salt);
string hashedPwd =
FormsAuthentication.HashPasswordForStoringInConfigFile(
saltAndPwd, "sha1");
return hashedPwd;
}
#endregion
private static SqlConnection BradOnline()
{
UserManagerTestEntities DBContext = new UserManagerTestEntities();
string connectionstring = DBContext.Database.Connection.ConnectionString;
SqlConnection conn = new SqlConnection(connectionstring);
return conn;
}
public List<string> groups()
{
List<string> groups = new List<string>();
using (SqlConnection conn = BOnline())
{
using (var command = new SqlCommand("Select name from aspnet_Custom_Groups", conn))
{
try
{
conn.Open();
command.CommandType = CommandType.Text;
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataSet dataset = new DataSet();
adapter.Fill(dataset);
foreach (DataRow dr in dataset.Tables[0].Rows)
{
groups.Add(dr["name"].ToString());
}
}
catch (SqlException ex)
{
ex.ToString();
}
return groups;
}
}
}
public static List<string> CreateUser(Models.vw_UserManager_Model_Add_Users newUser)
{
List<string> outcome = new List<string>();
try
{
using (SqlConnection conn = BOnline())
{
conn.Open();
UserManager.Models.vw_UserManager_Model_Add_Users model = new Models.vw_UserManager_Model_Add_Users();
using (var command = new SqlCommand("sp_UserManager_Add", conn))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#salutation", SqlDbType.NVarChar).SqlValue = newUser.salutation;
command.Parameters.Add("#username", SqlDbType.NVarChar).SqlValue = newUser.email;
command.Parameters.Add("#firstname", SqlDbType.NVarChar).SqlValue = newUser.firstname;
command.Parameters.Add("#lastname", SqlDbType.NVarChar).SqlValue = newUser.lastname;
command.Parameters.Add("#password", SqlDbType.NVarChar).SqlValue = newUser.password;
string salt = CreateSalt(20);
string passwordSalt = CreatePasswordHash(newUser.password, salt);
command.Parameters.Add("#passwordsalt", SqlDbType.NVarChar).SqlValue = passwordSalt;
command.Parameters.Add("#passwordquestion", SqlDbType.NVarChar).SqlValue = "test";
command.Parameters.Add("#passwordanswer", SqlDbType.NVarChar).SqlValue = "test";
command.Parameters.Add("#email", SqlDbType.NVarChar).SqlValue = newUser.email;
command.Parameters.Add("#CurrentTimeUtc", SqlDbType.DateTime).SqlValue = DateTime.UtcNow;
switch (newUser.isactive)
{
case true:
command.Parameters.Add("#isapproved", SqlDbType.TinyInt).SqlValue = 1;
break;
case false:
command.Parameters.Add("#isapproved", SqlDbType.TinyInt).SqlValue = 0;
break;
}
switch (newUser.alfConnect)
{
case true:
command.Parameters.Add("#Connect", SqlDbType.TinyInt).SqlValue = 1;
break;
case false:
command.Parameters.Add("#Connect", SqlDbType.TinyInt).SqlValue = 0;
break;
}
switch (newUser.alfIntelligence)
{
case true:
command.Parameters.Add("#Intelligence", SqlDbType.TinyInt).SqlValue = 1;
break;
case false:
command.Parameters.Add("#Intelligence", SqlDbType.TinyInt).SqlValue = 0;
break;
}
switch (newUser.brad)
{
case true:
command.Parameters.Add("#rad", SqlDbType.TinyInt).SqlValue = 1;
break;
case false:
command.Parameters.Add("#rad", SqlDbType.TinyInt).SqlValue = 0;
break;
}
command.Parameters.Add("#ApplicationName", SqlDbType.NVarChar).SqlValue = "bradlink";
command.Parameters.Add("#Group", SqlDbType.NVarChar).SqlValue = newUser.group_name;
int rowsCreated = command.ExecuteNonQuery();
if (rowsCreated > 0)
{
outcome.Add("New user created successfully.");
foreach (SqlParameter p in command.Parameters)
{
outcome.Add(p.Value.ToString());
}
}
}
}
}
catch (Exception ex)
{
List<string> error = new List<string>();
error.Add("Error creating new user. Check error message for more details.");
error.Add(ex.Message);
}
return outcome;
}
}
}
My view for form submission
<!-- Declare model to be used for view -->
#model UserManager.Models.vw_UserManager_Model_Add_Users
#{
ViewBag.Title = "Create New User";
}
<h2>
CreateUser</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>New User Details</legend>
<div class="editor-label">
#Html.LabelFor(Model => Model.salutation)
</div>
<div class="editor-field">
#Html.EditorFor(model => Model.salutation)
#Html.ValidationMessageFor(model => Model.salutation)
</div>
<div class="editor-label">
#Html.LabelFor(Model => Model.firstname)
</div>
<div class="editor-field">
#Html.EditorFor(model => Model.firstname)
#Html.ValidationMessageFor(model => Model.firstname)
</div>
<div class="editor-label">
#Html.LabelFor(Model => Model.lastname)
</div>
<div class="editor-field">
#Html.EditorFor(model => Model.lastname)
#Html.ValidationMessageFor(model => Model.lastname)
</div>
<div class="editor-label">
#Html.LabelFor(Model => Model.password)
</div>
<div class="editor-field">
#Html.EditorFor(model => Model.password)
#Html.ValidationMessageFor(model => Model.password)
</div>
<div class="editor-label">
#Html.LabelFor(Model => Model.email)
</div>
<div class="editor-field">
#Html.EditorFor(model => Model.email)
#Html.ValidationMessageFor(model => Model.email)
</div>
<div class="editor-label">
#Html.LabelFor(Model => Model.isactive)
</div>
<div class="editor-field">
#Html.EditorFor(model => Model.isactive)
#Html.ValidationMessageFor(model => Model.isactive)
</div>
<div class="editor-label">
#Html.Label("Group Name")
<!-- GroupName -->
</div>
<div class="editor-field">
#Html.EditorFor(model => Model.group_name, new { ID = "group_name" })
#Html.ValidationMessageFor(model => Model.group_name)
</div>
<div class="editor-label">
#Html.Label("Subscription Options")
<!-- GroupName -->
</div>
<div class="editor-field">
#Html.Label("Connect")
#Html.CheckBoxFor(Model => Model.Connect)
#Html.Label("ALF Intelligence")
#Html.CheckBoxFor(Model => Model.Intelligence)
#Html.Label("BRAD")
#Html.CheckBoxFor(Model => Model.rad)
</div>
<p>
<input type="submit" value="Create" onclick="return submitWith();"/>
<span id="validationMessage"></span>
</p>
</fieldset>
<div>
#Html.ActionLink("Back to List", "Index")
</div>
}
<script type="text/javascript">
// Count checkboxes that are checked.
function submitWith() {
var checkedCount = $("input:checked").length;
var valid = checkedCount > 0;
if (!valid) {
$('#validationMessage').html('You must select at least one option');
}
return valid;
}
</script>
<script type="text/javascript">
$(document).ready(function () {
$("#group_name").autocomplete('#Url.Action("LookUpGroupName")', // Call LookUpGroupName ActionResult in UserManager Controller
{
dataType: 'json',
parse: function (data) {
var rows = new Array();
for (var i = 0; i < data.length; i++) {
rows[i] = {
data: data[i],
value: data[i].group,
result: data[i].group
}
}
return rows;
},
formatItem: function (row, i, max) {
return row.group;
},
width: 300,
highlight: false,
multiple: false
}); // End of autocomplete
});
</script>
Any advice for handling this?

[HttpPost]
public ActionResult CreateUser(vw_UserManager_Model_Add_Users newUser)
{
try
{
if (ModelState.IsValid)
{
//var data = new UserManager.Models.UserManagerTestEntities();
// Pass model to Data Layer
List<string> outcome = UserManager.DAL.CreateUser(newUser);
//data.SaveChanges();
}
return View();
}
catch (Exception ex)
{
return RedirectToAction("showError", ex.Message);
}
}
public ActionResult showError(String sErrorMessage)
{
//All we want to do is redirect to the class selection page
ViewBag.sErrMssg = sErrorMessage;
return PartialView("ErrorMessageView");
}
I'd do something along these lines.

You Can use TempData for showing the Message.
For e.g. In your controller action you can set the TempData Like
TempData["SuccessMsg"] ="Record Saved Successfully.
Then return the view you want to return and Use TempData["SuccessMsg"] in that View.
e.g.
#model UserManager.Models.vw_UserManager_Model_Add_Users
#{
ViewBag.Title = "Create New User";
}
<h2>
CreateUser</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
if(TempData["SuccessMsg"]!=null)
{
<div>TempData["SuccessMsg"].ToString()</div>
}
}

Related

Cascading Drop Down in ASP.NET Core using Razor and jQuery

I've been trying to populate two dropdown list from my database. The first one is populated on form load, and I want to fill the second after the user selects a value in the first one.
I have followed and adapted this tutorial. But with no luck.
My Controller
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Oracle.ManagedDataAccess.Client;
using MaterialProjectMaterials.Models;
using UserProfile.Models;
using System.Data;
using Microsoft.AspNetCore.Http;
namespace MaterialProject.Controllers
{
public class MaterialsController : Controller
{
private readonly OracleConnection con = new OracleConnection(GetConString.ConString());
public IActionResult Materials()
{
List<Brands> brandslist = new List<Brands>();
brandslist.Insert(0, new Brands { BCodeID = 0, BDescr = "--Select Brand--" });
//Getting Data from Database using EntityFrameworkCore
con.Open();
string b_query = "SELECT codeID, descr FROM itemcategory WHERE codeID LIKE ('3%') AND LENGTH(codeID)= 3 and rownum<=2 ORDER BY descr";
OracleCommand b_cmd = new OracleCommand(b_query, con);
OracleDataAdapter b_da = new OracleDataAdapter(b_cmd);
DataTable b_dt = new DataTable();
b_da.Fill(b_dt);
foreach (DataRow b_rb in b_dt.Rows)
{
brandslist.Add(new Brands
{
BCodeID = Convert.ToInt64(b_rb["codeID"]),
BDescr = b_rb["descr"].ToString()
});
}
con.Close();
ViewBag.BrandsList = brandslist;
return View();
}
[HttpPost]
public IActionResult Materials(Brands objbrand, FormCollection formCollection)
{
//Validation
if (objbrand.BCodeID == 0)
ModelState.AddModelError("", "Select Brand");
else if (objbrand.VCodeID == 0)
ModelState.AddModelError("", "Select Volume");
//Getting selected Value
var BCodeID = HttpContext.Request.Form["BCodeID"].ToString();
var VCodeID = HttpContext.Request.Form["VCodeID"].ToString();
//Setting Data back to ViewBag after Posting Form
List<Brands> brandslist = new List<Brands>();
brandslist.Insert(0, new Brands { BCodeID = 0, BDescr = "--Select Brand--" });
//Getting Data from Database
con.Open();
string b_query = "SELECT codeID, descr FROM itemcategory WHERE codeID LIKE ('3%') AND LENGTH(codeID)= 3 ORDER BY descr";
OracleCommand b_cmd = new OracleCommand(b_query, con);
OracleDataAdapter b_da = new OracleDataAdapter(b_cmd);
DataTable b_dt = new DataTable();
b_da.Fill(b_dt);
foreach (DataRow b_rb in b_dt.Rows)
{
brandslist.Add(new Brands
{
BCodeID = Convert.ToInt64(b_rb["codeID"]),
BDescr = b_rb["descr"].ToString()
});
}
con.Close();
//Assing BCodeID to ViewBag.BrandsList
ViewBag.BrandsList = brandslist;
return View(objbrand);
}
public JsonResult GetVolumes(Int64? BCodeID)
{
if (BCodeID == null)
{
throw new ArgumentNullException(nameof(BCodeID));
}
List<Volume> volumelist = new List<Volume>();
volumelist.Insert(0, new Volume { VCodeID = 0, VDescr = "--Select Volume--" });
//Getting Data from Database
con.Open();
string v_query = "SELECT DISTINCT IG.CODEID, IG.DESCR FROM MATERIAL M INNER JOIN ITEMGROUP IG ON M.IGPID = IG.CODEID INNER JOIN ITEMCATEGORY IC ON '3' || SUBSTR(M.ICTID, 3, 2) = IC.CODEID WHERE M.ICTID LIKE('3%') AND IC.CODEID =" + BCodeID + "ORDER BY CODEID";
OracleCommand v_cmd = new OracleCommand(v_query, con);
OracleDataAdapter v_da = new OracleDataAdapter(v_cmd);
DataTable v_dt = new DataTable();
v_da.Fill(v_dt);
foreach (DataRow v_dr in v_dt.Rows)
{
volumelist.Add(new Volume
{
VCodeID = Convert.ToInt64(v_dr["codeID"]),
VDescr = v_dr["descr"].ToString()
});
}
con.Close();
return Json(new SelectList(volumelist, "VCodeID", "VDescr"));
}
}
}
My View
#model MaterialProjectMaterials.Models.Brands
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
#{
<script src="~/lib/jquery/dist/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var items = "<option value='0'>--Select Volume--</option>";
$("VCodeID").html(items);
});
</script>
<script type="text/javascript">
$(document).ready(function () {
$("#BCodeID").change(function () {
var url = '#Url.Content("~/")' + "Materials/GetVolumes";
var ddlsource = "#BCodeID";
$.getJSON(url, { BCodeID: $(ddlsource).val() }, function (data) {
var items = '';
$("#VCodeID").empty();
$.each(data, function (i, volume) {
items += "<option value='" + volume.value + "'>" + volume.text + "</option>";
});
$("#VCodeID").html(items);
});
})
})
</script>
<form asp-controller="Materials" asp-action="Materials" method="post" class="form-horizontal" role="form">
<div class="form-group">
<div class="row">
<div class="alert-danger" asp-validation-summary="ModelOnly"></div>
<div class="col-xs-12 col-sm-6 col-lg-4">
<label asp-for="BDescr" class="control-label">Brands</label>
<select asp-for="BCodeID" class="form-control"
asp-items="#(new SelectList(ViewBag.BrandsList, "BCodeID", "BDescr"))"></select>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-xs-12 col-sm-6 col-lg-4">
<label class="control-label">Volume</label>
<select class="form-control" id="vCodeID" name="vDescr" asp-for="VCodeID"
asp-items="#(new SelectList(string.Empty, "VCodeID", "VDescr"))"></select>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-xs-12 col-sm-6 col-lg-4">
<input id="Submit1" type="submit" value="Submit" />
</div>
</div>
</div>
</form>
}
My Models
namespace MaterialProjectMaterials.Models
{
public class MaterialsModel
{
public DbSet<Brands> Brands { get; set; }
public DbSet<Volume> Volume { get; set; }
}
}
namespace MaterialProjectMaterials.Models
{
[Table("ITEMCATEGORY")]
public class Brands
{
[Key]
[Column("CODEID")]
public Int64 BCodeID { get; set; }
[Column("DESCR")]
public string BDescr { get; set; }
[NotMapped]
public Int64 VCodeID { get; set; }
}
}
namespace MaterialProjectMaterials.Models
{
[Table("IT_MATERIAL_VOLUMES")]
public class Volume
{
[Key]
[Column("VCODEID")]
public Int64 VCodeID { get; set; }
[Column("VDESCR")]
public string VDescr { get; set; }
[Column("BDESCR")]
public int BCodeID { get; set; }
}
}
The result when I run the project is that I can get the values in the first dropdownlist, but when I select a value I did not get anything back to the second dropdownlist.
I would appreciate any help.
Thanks in advance.
Update 1
In the debugger I get the follows error concerning the javascrips
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:44373/lib/jquery/jquery.js
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 3.5252ms 404
Unhandled exception at line 4, column 9 in https://localhost:44373/Home/Login
0x800a1391 - JavaScript runtime error: '$' is undefined
as for the line
Unhandled exception at line 4, column 9 in https://localhost:44373/Home/Login
it says that the script locate at ~/Home/Login but my script are at ~/Materials/Materials
Finally my .js files are locate at
~\MaterialProject\wwwroot\lib\jquery
Any help would appreciate a lot!
Update 2
I solve my problem
I use instead of and also I replace
<div class="form-group">
<div class="row">
<div class="col-xs-12 col-sm-6 col-lg-4">
<label class="control-label">Volume</label>
<select class="form-control" id="vCodeID" name="vDescr" asp-for="VCodeID"
asp-items="#(new SelectList(string.Empty, "VCodeID", "VDescr"))"></select>
</div>
</div>
</div>
with
<div class="form-group">
<div class="row">
<div class="col-xs-12 col-sm-6 col-lg-4">
<label asp-for="VDescr" class="control-label">Volume</label>
<select asp-for="VCodeID" class="form-control"
asp-items="#(new SelectList(string.Empty, "VCodeID", "VDescr"))"></select>
</div>
</div>
</div>

C# mvc saving deviceconfig as new config id in foreign table

I am trying to create a system where it is possible to add/ change device configurations. The user should be able to add / delete rows at the same time.
Everytime a config is saved, a new config_id is created and VersionNr is increased.
I am 100% sure I am doing something wrong, and what is going wrong. But I dont know how to fix it or improve it.
Here is my code:
public ActionResult Edit(int? Id)
{
//create new list
var Device_Pricelist = new List<Device_Pricelist>(db.Device_Pricelist.Where(r => r.DeviceConfig.Device_config_id == Id));
//create new SelectList in Device_Pricelist
var SelectedCMI = (from d in db.pricelist
select new { d.Price_id, Value = d.bas_art_nr }).Distinct();
//call viewbag based on SelectedCMI query
ViewBag.SelectedCMI = new SelectList(SelectedCMI.Distinct(), "Price_id", "Value");
return View(Device_Pricelist);
}
public ActionResult Edit([Bind(Include = "id,Device_config_id,Price_id,amount,assembly_order")]DeviceConfig deviceConfig, List<Device_Pricelist> device_Pricelists)
{
if (ModelState.IsValid)
{
try
{
try
{
db.DeviceConfig.Add(deviceConfig).Device_config_id = deviceConfig.Device_config_id++;
db.DeviceConfig.Add(deviceConfig).device_type_id = deviceConfig.device_type_id = 13;
db.DeviceConfig.Add(deviceConfig).Active = true;
//Needs to be based on current VersionNr in deviceConfig
db.DeviceConfig.Add(deviceConfig).VersionNr = deviceConfig.VersionNr + 1;
db.DeviceConfig.Add(deviceConfig).Date = deviceConfig.Date = DateTime.Now;
}
finally
{
foreach (var item in device_Pricelists)
{
db.Entry(item).State = EntityState.Added;
}
}
db.SaveChanges();
TempData["SuccesMessage"] = "Data is Succesfully saved";
return RedirectToAction("Index");
}
catch
{
TempData["AlertMessage"] = "Saving Data Failed, " + "Try Again";
}
}
return View(device_Pricelists);
}
view:
#model List<ConcremoteDeviceManagment.Models.Device_Pricelist>
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm("Edit", "Home", FormMethod.Post))
{
<h1>
#Html.DisplayName("Edit Configuration")
</h1>
<h2>
#* #Html.DisplayFor(model => model.DeviceType.name)<br />*#dammit
</h2>
if (TempData["AlertMessage"] != null)
{
<p class="alert alert-danger" id="FailMessage">#TempData["AlertMessage"]</p>
}
#Html.ValidationSummary(true)
#Html.AntiForgeryToken()
<div>
#* Add New*#
</div>
<table class="table table-hover" id="dataTable">
<tr>
<th class="table-row">
#Html.DisplayName("BAS artikelnummer")
</th>
<th class="table-row">
#Html.DisplayName("Beschrijving")
</th>
<th class="table-row">
#Html.DisplayName("Aantal")
</th>
<th class="table-row">
#Html.DisplayName("Bouw Volgorde")
</th>
<th class="table-row">
Add New Row
</th>
</tr>
#if (Model != null && Model.Count > 0)
{
int j = 0;
foreach (var item in Model)
{
<tr>
#Html.HiddenFor(a => a[j].id)
#Html.HiddenFor(a => a[j].Device_config_id)
#* #Html.HiddenFor(a => a[j].Price_id)*#
<td class="table-row">
#Html.DropDownListFor(a => a[j].Price_id, (IEnumerable<SelectListItem>)ViewBag.SelectedCMI, null, new { #class = "form-control" })
</td>
<td class="table-row">
#Html.DisplayFor(a => a[j].Pricelist.description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(a => a[j].Pricelist.description, "", new { #class = "text-danger" })
</td>
<td class="table-row">
#Html.EditorFor(a => a[j].amount, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(a => a[j].amount, "", new { #class = "text-danger" })
</td>
<td class="table-row">
#Html.EditorFor(a => a[j].assembly_order, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(a => a[j].assembly_order, "", new { #class = "text-danger" })
</td>
#*<td class="table-row">
#Html.DisplayFor(a => a[j].DeviceConfig.Date, new { htmlAttributes = new { #class = "form-control" } })
</td>*#
<td>
#if (j > 0)
{
Remove
}
</td>
</tr>
j++;
}
}
</table>
<input type="submit" value="Save Device Data" class="btn btn-primary" />
<button onclick="location.href='#Url.Action("Index", "Home")';return false; " class="btn btn-primary">Back to list</button>
}
#section Scripts{
#*#Scripts.Render("~/bundles/jqueryval")*#
<script language="javascript">
$(document).ready(function () {
//1. Add new row
$("#addNew").click(function (e) {
e.preventDefault();
var $tableBody = $("#dataTable");
var $trLast = $tableBody.find("tr:last");
var $trNew = $trLast.clone();
var suffix = $trNew.find(':input:first').attr('name').match(/\j+/);
$trNew.find("td:last").html('Remove');
$.each($trNew.find(':input'), function (i, val) {
// Replaced Name
var oldN = $(this).attr('name');
var newN = oldN.replace('[' + suffix + ']', '[' + (parseInt(suffix) + 1) + ']', '[' + suffix + ']', '[' + (parseInt(suffix) + 1) + ']', '[' + suffix + ']', '[' + (parseInt(suffix) + 1) + ']');
$(this).attr('name', newN);
//Replaced value
var type = $(this).attr('type');
//if (type.toLowerCase() == "text") {
// $(this).attr('value', '');
//}
// If you have another Type then replace with default value
$(this).removeClass("input-validation-error");
});
$trLast.after($trNew);
// Re-assign Validation
//var form = $("form")
// .removeData("validator")
// .removeData("unobtrusiveValidation");
//$.validator.unobtrusive.parse(form);
});
// 2. Remove
//$('a.remove').live("click", function (e) { --> this is for old jquery library
$('body').on("click", '#remove', function (e) {
e.preventDefault();
$(this).parent().parent().remove();
});
});
</script>
<script type="text/javascript">
function SelectedIndexChanged() {
//Form post
document.demoForm.submit();
}
</script>
I hope somebody is able to help me.
More information will be given when needed.
Your method accepts 2 parameters but you are only posting 1 object - List<Device_PriceList>. Let's assume you want to construct a new DeviceConfig based on the existing one, you should change your Action method to the following:
public ActionResult Edit(List<Device_Pricelist> device_Pricelists)
{
if (ModelState.IsValid)
{
try
{
var deviceConfig = db.DeviceConfig.Find(device_Pricelists.First().Device_config_id);
deviceConfig.device_type_id = 13;
deviceConfig.Active = true;
deviceConfig.VersionNr++;
deviceConfig.Date = DateTime.Now;
db.DeviceConfig.Add(deviceConfig);
foreach(var item in device_Pricelists)
{
item.Device_config_id = deviceConfig.Device_config_id;
}
db.Device_Pricelists.AddRange(device_Pricelists);
db.SaveChanges();
TempData["SuccesMessage"] = "Data is Succesfully saved";
return RedirectToAction("Index");
}
catch
{
TempData["AlertMessage"] = "Saving Data Failed, Try Again";
}
}
return View(device_Pricelists);
}
Remember when posting a list, you need to post complete sets of the object you're trying to map to. That is for example [0].Id, [0].Device_config_id (etc), [1].Id, [1].Device_config_id (etc).
Your JS doesn't seem correct, particularly the .replace(..) call with 6 parameters, so you're probably seeing lots of [0]s when you clone the rows. Some simpler JS that will get you the same result is:
var oldN = $(this).attr('name');
var idx = parseInt(oldN.substr(1, oldN.indexOf(']')));
var newN = oldN.replace('[' + idx + ']', '[' + (idx + 1) + ']');

EF7 MVC ASP.NET File upload in form

I'm trying to upload a file alongside with some model information.
In my table I already have a field 'image' (string) to save the relative URL to the image.
But I don't really know how to do the uploading itself.
I've already read a lot off tutorials, but they all use HttpPostedFileBase, which isn't supported anymore?
This is what I have thus far:
Upload page:
#using (Html.BeginForm("Lets", "Create", FormMethod.Post, new { #enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<fieldset>
<div class="form-group">
<div class="mdl-cell col-md-10 mdl-textfield mdl-js-textfield">
#Html.LabelFor(m => m.Lets.Name, new { #class="mdl-textfield__label" })
#Html.TextBoxFor(m => m.Lets.Name, new { #class= "form-control mdl-textfield__input" })
</div>
</div>
<div class="form-group">
<div class="mdl-cell col-md-10 mdl-textfield mdl-js-textfield">
#Html.LabelFor(m => m.Lets.Images)
<input type="file" name="LetsImages" id="m.Lets.Images" /> <br />
</div>
</div>
<div class="form-group">
<div class="mdl-cell col-md-10 mdl-textfield mdl-js-textfield">
#Html.LabelFor(m => m.Lets.Description, new { #class="mdl-textfield__label" })
#Html.TextBoxFor(m => m.Lets.Description, new { #class= "form-control mdl-textfield__input" })
</div>
</div>
<div class="form-group">
<div class="mdl-cell col-md-10 mdl-textfield mdl-js-textfield">
#Html.LabelFor(m => m.Lets.Credits, new { #class="mdl-textfield__label" })
#Html.TextBoxFor(m => m.Lets.Credits, new { #class= "form-control mdl-textfield__input" })
</div>
</div>
<div class="form-group">
<div class="mdl-cell col-md-10">
#Html.LabelFor(m => m.Lets.Group)
#Html.DropDownListFor(m => m.Lets.GroupId, new SelectList(Model.Groups, "Id", "Name"), "-- Selecteer een Groep --", new { #class= "form-control" })
</div>
</div>
#Html.ActionLink("Terug naar het overzicht", "Index", new { }, new { #class= "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect" })
<input type="submit" value="Save" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect" />
</fieldset>
}
Controller:
[HttpGet]
public IActionResult Create()
{
var model = new LetsViewModel
{
Lets = new Lets(),
Groups = _kletsContext.Groups.AsEnumerable(),
Letses = _kletsContext.Lets.AsEnumerable().OrderBy(m => m.Name)
};
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(LetsViewModel model)
{
LetsViewModel viewModel = null;
try
{
if(!ModelState.IsValid)
throw new Exception("The Lets model is not valid!");
var letsImage = "INSERT LOGIC FOR IMAGEUPLOAD HERE?";
model.Lets.UserId = User.GetUserId();
model.Lets.StatusId = 1;
model.Lets.Images = letsImage;
_kletsContext.Lets.Add(model.Lets);
if (_kletsContext.SaveChanges() == 0)
{
throw new Exception("The Lets model could not be saved!");
}
//Success(CreateMessage(ControllerActionType.Create, "klets", model.Name), true);
return RedirectToAction("Index", "Home");
}
catch(Exception ex)
{
ModelState.AddModelError(string.Empty, "Unable to save changes.");
viewModel = new LetsViewModel
{
Lets = model.Lets,
Letses = _kletsContext.Lets.AsEnumerable().OrderBy(m => m.Name)
};
}
return View(viewModel);
}
I've added the place where I think the logic should come?
So what I want to do is:
Upload the Image to a folder
Rename it
Store the relative path as a string to the db.
Thank you
There is no HttpPostedFileBase in MVC6, you have to use IFormFile like this:
public FileDetails UploadSingle(IFormFile file)
{
FileDetails fileDetails;
using (var reader = new StreamReader(file.OpenReadStream()))
{
var fileContent = reader.ReadToEnd();
var parsedContentDisposition = ContentDispositionHeaderValue.Parse(file.ContentDisposition);
fileDetails = new FileDetails
{
Filename = parsedContentDisposition.FileName,
Content = fileContent
};
}
return fileDetails;
}
You can upload images using handlers , link to tutorials are
http://www.c-sharpcorner.com/blogs/uploading-files-using-jquery-ajax-in-asp-net1
http://www.binaryintellect.net/articles/f2a2f1ee-e18a-416b-893e-883c800f83f4.aspx
http://www.dotnetjalps.com/2011/12/async-file-upload-with-jquery-and.html?m=1
These tutorials are using jquery to pass the image to the handler and then handler saving the image in the folder. You can rename the image before uploading to the folder and get back the saved image name in response and then save image name along with other model properties.
I eventually got it working by:
include using Microsoft.AspNet.Hosting; and using System.IO;
using System.Net.Http.Headers;
Add public IHostingEnvironment _environment { get; set;}
to your controller (I added it to my commoncontroller, and then it's available to me on my controller)
Then in my create:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(LetsViewModel model, IFormFile LetsImages)
{
LetsViewModel viewModel = null;
try
{
if(!ModelState.IsValid)
throw new Exception("The Lets model is not valid!");
if(LetsImages != null)
{
var targetDirectory = Path.Combine(_environment.WebRootPath, string.Format("images/uploads"));
var fileName = ContentDispositionHeaderValue
.Parse(LetsImages.ContentDisposition)
.FileName
.Trim('"');
var savePath = Path.Combine(targetDirectory, fileName);
var relPath = "/images/uploads/" + fileName;
try
{
LetsImages.SaveAs(savePath);
model.Lets.Images = relPath;
}
catch
{
throw new Exception("There was a problem with saving the file!");
}
}
else
{
model.Lets.Images = null;
}
model.Lets.UserId = User.GetUserId();
model.Lets.StatusId = 1;
_kletsContext.Lets.Add(model.Lets);
if (_kletsContext.SaveChanges() == 0)
{
throw new Exception("The Lets model could not be saved!");
}
//Success(CreateMessage(ControllerActionType.Create, "klets", model.Name), true);
return RedirectToAction("Index", "Home");
}
catch(Exception ex)
{
ModelState.AddModelError(string.Empty, "Unable to save changes.");
viewModel = new LetsViewModel
{
Lets = model.Lets,
Groups = _kletsContext.Groups.AsEnumerable(),
Letses = _kletsContext.Lets.AsEnumerable().OrderBy(m => m.Name)
};
}
return View(viewModel);
}
Just make sure you've created the folder where the images should belong, else it's not going to work without any error!
Thanks everybody for your help!

Trying to use form post without entity framework -- I Gave up, but will keep it open in case it helps someone...somewhere

While trying to get the basic CRUD to work in my Web application I have run into some problems. First, this is how I connect to my database:
public class DatabaseController : Controller
{
protected MySqlConnection conn;
public DatabaseController()
{
//Vul hier de juiste gegevens in!!
conn = new MySqlConnection("Server=localhost;Database=db;Uid=pw;Pwd=pw;");
}
}
and this is how I load my rows initially:
public Klant getAll(string naam)
{
MySqlTransaction trans = null;
Klant klanten = new Klant();
conn.Open();
trans = conn.BeginTransaction();
try
{
string selectQuery = #"select * from klant;";
MySqlCommand cmd = new MySqlCommand(selectQuery, conn);
//MySqlParameter naamParam = new MySqlParameter("#naam", MySqlDbType.VarChar);
//naamParam.Value = "%" + naam + "%";
//cmd.Parameters.Add(naamParam);
cmd.Prepare();
MySqlDataReader dataReader = cmd.ExecuteReader();
while (dataReader.Read())
{
int IdKlant = dataReader.GetInt32("idklant");
String Naam = dataReader.GetString("naam");
String Woonplaats = dataReader.GetString("woonplaats");
DateTime Geboortedatum = dataReader.GetDateTime("geboortedatum");
String Geslacht = dataReader.GetString("geslacht");
String Beschrijving = dataReader.GetString("beschrijving");
klanten.idklant = IdKlant;
klanten.naam = Naam;
klanten.woonplaats = Woonplaats;
klanten.geboortedatum = Geboortedatum;
klanten.geslacht = Geslacht;
klanten.beschrijving = Beschrijving;
}
}
catch (Exception e)
{
throw new Exception("Product niet toegevoegd: " + e);
}
finally
{
conn.Close();
}
return klanten;
}
and this is how I load them in the view:
#{ if (#Model == null)
{
<div>geen producten gevonden</div>
}
else
{
<div></div><br>
foreach (Klant kl in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => kl.idklant)
</td>
<td>
#Html.DisplayFor(modelItem => kl.naam)
</td>
<td>
#Html.ActionLink("Details", "ShowKlant", new { id = kl.idklant }) |
#Html.ActionLink("Edit", "ShowKlant", new { id = kl.idklant }) |
#Html.ActionLink("Delete", "ShowKlant", new { id = kl.idklant })<br /><br />
</td>
</tr>
}
}
}
Read operations work fine(to a certain degree).
I am capable of loading all the rows from my database, each with a Details/edit/delete/ option which uses the correct id from each respective row.
If I click on the customer with the id3, this link is loaded:
http://localhost:51596/Home/ShowKlant/3
Even when using the [HttpPost] overload above the actionResult like so:
public ActionResult ShowKlant(int? idklant)
{
Klant k = new Klant();
KlantDBController sc = new KlantDBController();
k = sc.getById(idklant);
return View(k);
}
[HttpPost]
public ActionResult ShowKlant(Klant klant)
{
return View(klant);
}
The fields don't get filled.
This is how the view looks in code:
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Movie</legend>
<div class="editor-label">
#Html.LabelFor(model => model.idklant)
</div>
<div class="editor-label">
#Html.EditorFor(model => model.idklant)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.naam)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.naam)
#Html.ValidationMessageFor(model => model.naam)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.woonplaats)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.woonplaats)
#Html.ValidationMessageFor(model => model.woonplaats)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.geboortedatum)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.geboortedatum)
#Html.ValidationMessageFor(model => model.geboortedatum)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.geslacht)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.geslacht)
#Html.ValidationMessageFor(model => model.geslacht)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.beschrijving)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.beschrijving)
#Html.ValidationMessageFor(model => model.beschrijving)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
I am probably missing something small...... but I think the problem might lie in how I load the data for the details page..... I just can't see it :/
My getById code is essentially the same as getAll.
The Get By ID Code is this
string selectQuery = #"select * from klant where idklant = #idklant;";
This is what is different from my usual SQL.
If I do this:
string selectQuery = #"select * from klant;";
it fills the data, but only with the last row in the the database, it doesnt matter wich of the customers I use, it returns/fills the last row.
everything:
unpleasant result:
Your issue is that #idklant never has a value set.
You have a function called getById(int idklant)
MySqlCommand cmd = new MySqlCommand(selectQuery, conn);
MySqlParameter idklantParam = new MySqlParameter("#idklant", MySqlDbType.Int32);
cmd.Parameters.Add(idklantParam);
And you never set the value of the parameter, only the type. Before cmd.Parameters.Add you should have
idklantParam.value = idklant; // or whatever your parameter name is in your method

Keep values of dropdownlist (MVC)

How can I keep values of dropdownlist after return from a submit?
I have the following structure.
On controller:
[HttpPost]
public ActionResult Cadastro(CadastroViewModel viewModel)
{
try
{
var usuario = Mapper.Map<CadastroViewModel, Usuario>(viewModel);
servicoDeAplicacaoDeUsuario.Inserir(usuario);
}
catch (ValidationException validationException)
{
this.ModelState.Clear();
foreach (var error in validationException.Errors)
this.ModelState.AddModelError(error.PropertyName, error.ErrorMessage);
return View("Cadastro", viewModel);
}
return RedirectToAction("Index", "Home");
}
So above it will return some validation errors, but the viewModel does not have the filled list (dropdown) to return.
#using (Html.BeginForm("Cadastro", "Cadastro", FormMethod.Post))
{
<ul class="login-signup-list">
<li>
#Html.TextBoxFor(f => f.NomeCompleto, new { #class = "span10", autofocus = "autofocus", placeholder = RecursoDeCadastro.NomeCompleto, maxlength = 100 })
</li>
<li>
#Html.TextBoxFor(f => f.Email, new { #class = "span10", type="email", placeholder = RecursoDeCadastro.Email, maxlength = 100 })
</li>
<li>
#Html.TextBoxFor(f => f.Senha, new { #class = "span10", type="password", placeholder = RecursoDeCadastro.Senha, maxlength = 50 })
</li>
<li>
#Html.DropDownListFor(m => m.IdPais, new SelectList(Model.Paises, "Id", "Nome"), new { #class = "span10" } )
</li>
<li>
#Html.DropDownListFor(m => m.IdUF, new SelectList(Model.UFs, "Id", "Nome"), new { #class = "span10" } )
</li>
<li>
#Html.DropDownListFor(m => m.IdMunicipio, new SelectList(Model.Municipios, "Id", "Nome"), new { #class = "span10" } )
</li>
<li>
<button class="btn btn-primary">#RecursoDeCadastro.CriarConta</button>
</li>
// ... ?
}
I could take every list from database again and set it´s value using the Id (IdUF for example) that came with viewModel on post, because i'm losing only the list. But I think that it´s not necessary that request to database again.
Is there a workaround for it?
Can I use session by logged user? How?
Thanks.
Wilton Ruffato Wonrath

Categories

Resources