C# MVC API send values using GET queryString? - api

This is first time I have tried to make an API using MVC4. So far it is working ok.
For practice I want to try and send my model using a queryString in the GET method instead of my current POST send method.
As I have no clue how to start, and whats need to be done ? Can you come with some advices ?
Can I have the Index view as it is ? or anything need to be changed ?
I also would like to keep the curent GET method I have to show the list, I guess that will interfere if I add a new GET method fot sending querystring ?
All advices is helpful here ^_^
namespace MessageHandler.Models
{
public class Message
{
public int Id { get; set; }
public double Amount { get; set; }
public string PaymentMessage { get; set; }
public string Name { get; set; }
public string Adress { get; set; }
}
}
namespace MessageHandler.Services
{
public class MessageRepository
{
private const string CacheKey = "MessageStore";
public MessageRepository()
{
var ctx = HttpContext.Current;
if (ctx != null)
{
if (ctx.Cache[CacheKey] == null)
{
var messages = new Message[]
{
new Message
{
Id = 1, PaymentMessage = "payment for order 23434",
Name = "Christer Glenning", Adress = "Grenvagen 24",
Amount = 2300
},
new Message
{
Id = 2, PaymentMessage = "payment for order 24354",
Name = "Carl Ingemar", Adress = "Regnbagen 446",
Amount = 44
}
};
ctx.Cache[CacheKey] = messages;
}
}
}
public Message[] GetAllMessages()
{
var ctx = HttpContext.Current;
if (ctx != null)
{
return (Message[])ctx.Cache[CacheKey];
}
return new Message[]
{
new Message
{
Id = 0,
Name = "placeHolder"
}
};
}
public bool SaveMessage(Message message)
{
var ctx = HttpContext.Current;
if (ctx != null)
{
try
{
var currentData = ((Message[])ctx.Cache[CacheKey]).ToList();
currentData.Add(message);
ctx.Cache[CacheKey] = currentData.ToArray();
return true;
}
catch (Exception exp)
{
Console.WriteLine(exp.Message);
return false;
}
}
return false;
}
}
}
using MessageHandler.Models;
using MessageHandler.Services;
namespace MessageHandler.Controllers
{
public class MessageController : ApiController
{
private MessageRepository repo;
public MessageController()
{
this.repo = new MessageRepository();
}
public Message[] Get()
{
return repo.GetAllMessages();
}
public HttpResponseMessage Post(Message message)
{
this.repo.SaveMessage(message);
var response = Request.CreateResponse<Message>(System.
Net.HttpStatusCode.Created, message);
return response;
}
}
}
<header>
<div class="content-wrapper">
<div class="float-left">
<p class="site-title">
API</p>
</div>
</div>
</header>
<div id="body">
<ul id="messages"></ul>
<form id="saveMessageForm" method="post">
<h3>Create a new Message</h3>
<p>
<label for="messageId">Id:</label>
<input type="text" name="Id" />
</p>
<p>
<label for="messagePaymentMessage">Message:</label>
<input type="text" name="PaymentMessage" />
</p>
<p>
<label for="messageName">Name:</label>
<input type="text" name="Name" />
</p>
<p>
<label for="messageAdress">Adress:</label>
<input type="text" name="Adress" />
</p>
<p>
<label for="messageAmount">Amount:</label>
<input type="text" name="Amount" />
</p>
<input type="button" id="saveMessage" value="Save" />
</form>
</div>
#section scripts
{
<script type="text/javascript">
$(function()
{
$.getJSON('/api/message', function (messagesJsonPayload) {
$(messagesJsonPayload).each(function (i, item) {
$('#messages').append('<li>' + item.PaymentMessage + '</li>' +
'<li>' + item.Name + '</li>' +
'<li>' + item.Adress + '</li>' +
'<li>' + '$' + item.Amount.toFixed(2) + '</li>' + '<br>');
});
});
});
</script>
<script type="text/javascript">
$('#saveMessage').click(function()
{
$.post("api/message",
$("#saveMessageForm").serialize(),
function(value)
{
$('#messages').append('<li>' + value.PaymentMessage + '</li>' +
'<li>' + value.Name + '</li>' +
'<li>' + value.Adress + '</li>' +
'<li>' + '$' + value.Amount.toFixed(2) + '</li>');
},
"json"
);
});
</script>
}

Well, I'm not expert for build an API, but I think you need to step back and learning concept for building an API (specially the REST one).
here's the link that maybe useful for you:
build-restful-apis-with-aspnet-web-api
REST API Tutorial

Related

Properties set to null when OnPost handler is called in razor page

I have a page with 2 buttons each one with their handler methods (OnPostAsync and OnPostResend) and 2 properties (LoginType and DocumentNumber) when OnPostAsync is called, properties have their values and the method works as expected but when the second button is clicked and OnPostResend is called properties are set to null. Why is this happenning and how can I prevent it?
This is the .cshtml file:
#page
#model SATCloudWebApp.Areas.Identity.Pages.Account.EnterOtpModel
#{
ViewData["Title"] = $"Ingrese el código de confirmación";
string device = TempData["PhoneNumber"]
}
}
<h2>#ViewData["Title"]</h2>
<div class="row">
<div class="col-md-6">
<h4>Por favor digite el código enviado a su #device. </h4>
<form method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Input.OtpCode"></label>
<input asp-for="Input.OtpCode" class="form-control" />
<span asp-validation-for="Input.OtpCode" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-info">Siguiente</button>
</form>
<href>
<form asp-page-handler="resend" method="post">
<button id="resendToken" type="submit" class="btn btn-dark">Reenviar código</button>
</form>
</href>
</div>
</div>
This is the page model:
namespace Name
{
[AllowAnonymous]
public class EnterOtpModel : PageModel
{
// constructor goes here ...
[BindProperty]
public string LoginType { get; set; }
[BindProperty]
public string DocumentNumber { get; set; }
[BindProperty]
public InputModel Input { get; set; }
public class InputModel
{
[Required(ErrorMessage = "Ingrese el código enviado.")]
[Display(Name = "Código de inicio de sesión")]
public string OtpCode { get; set; }
}
public IActionResult OnGet(string loginType, string documentNumber)
{
if (User.Identity.IsAuthenticated)
{
return RedirectToPage("~/LoginWithOtp");
}
else
{
LoginType = loginType;
List<SATCloudUser> _users = new List<SATCloudUser>();
_users = _userManager.Users.Where(x => x.DocumentNumber == documentNumber).ToList();
SATCloudUser _satUser = _users[0];
TempData["Username"] = _satUser.Email;
TempData["PhoneNumber"] = _satUser.PhoneNumber;
return Page();
}
}
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
List<SATCloudUser> _users = new List<SATCloudUser>();
_users = _userManager.Users.Where(x => x.DocumentNumber == DocumentNumber).ToList();
SATCloudUser _satUser = _users[0];
if (ModelState.IsValid)
{
var result = await _userManager.VerifyTwoFactorTokenAsync(_satUser, "Email", Input.OtpCode);
if (result)
{
returnUrl = returnUrl ?? Url.Content("~/Home/Index");
var auth = await HttpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme);
var authenticationMethod = auth?.Principal?.FindFirstValue(ClaimTypes.AuthenticationMethod);
await _signInManager.SignInAsync(_satUser, false, authenticationMethod);
return LocalRedirect(returnUrl);
}
else
{
TempData["Username"] = _satUser.Email;
TempData["PhoneNumber"] = _satUser.PhoneNumber;
TempData["messageEnterOtp"] = "InvalidToken";
return Page();
}
}
else
{
return Page();
}
}
public async void OnPostResendAsync()
{
List<SATCloudUser> _users = new List<SATCloudUser>();
_users = _userManager.Users.Where(x => x.DocumentNumber == DocumentNumber).ToList();
SATCloudUser _satUser = _users[0];
var token = await _userManager.GenerateTwoFactorTokenAsync(_satUser, "Email");
if(LoginType == "sms")
{
AlertsManager _alertManager = new AlertsManager();
string phoneNumber = "+57" + _satUser.PhoneNumber;
string message = $"Código de inicio de sesión en Better Together SE: {token}. Por favor no comparta este código.";
await _alertManager.SendTextMessageAsync(phoneNumber, message);
}
else if(LoginType == "email")
{
EmailManager _emailManager = new EmailManager();
await _emailManager.NewTokenEmail(_satUser.Email, token);
}
}
}
}
A new instance of the EnterOtpModel class is created for each request. So the state of its properties is not preserved between different requests. You can add hidden input elements inside the resend form so that LoginType and DocumentNumber are re-sent again to the EnterOtpModel.
<form asp-page-handler="resend" method="post">
<input type="hidden" asp-for="LoginType" />
<input type="hidden" asp-for="DocumentNumber" />
<button id="resendToken" type="submit" class="btn btn-dark">Reenviar código</button>
</form>

I wanted to perform crud operations for Admin Panel of an ecommerce project but not able to edit image gallery in asp.net core

ProductModel class file
public class ProductModel
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public string ProductDesc { get; set; }
public string Image { get; set; }
public IFormFile Img { get; set; }
public IFormFileCollection GalleryImages { get; set; }
public List<ProductGalleryModel> ProductGallery { get;set;}
}
ProductGalleryModel class file
public class ProductGalleryModel
{
public int ID { get; set; }
public int ProductId { get; set; }
public string Name { get; set; }
public string URL { get; set; }
public IFormFileCollection GalleryImages { get; set; }
public List<ProductGalleryModel> ProductGallery { get; set; }
}
ProductController class file
public class ProductController : Controller
{
private readonly IProductRepository _productRepository = null;
public ProductController(IProductRepository productRepository)
{
_productRepository = productRepository;
}
public async Task<IActionResult> AddNewProduct(bool isSuccess = false, int prodId = 0)
{
ViewBag.Categories = new SelectList(await _categoryRepository.GetAllCategories(), "CatID", "CategoryName");
ViewBag.IsSuccess = isSuccess;
ViewBag.ProductID = prodId;
return View();
}
[HttpPost]
public async Task<IActionResult> AddNewProduct(ProductModel productModel)
{
if (ModelState.IsValid)
{
if (productModel.Img1 != null)
{
string folder = "images/product/cover/";
productModel.Image1 = await UploadImage(folder, productModel.Img1);
}
if (productModel.GalleryImages != null)
{
string folder = "images/product/cover/gallery/";
productModel.ProductGallery = new List<ProductGalleryModel>();
foreach (var file in productModel.GalleryImages)
{
var gallery = new ProductGalleryModel()
{
Name = file.FileName,
URL = await UploadImage(folder, file)
};
productModel.ProductGallery.Add(gallery);
}
}
var id = await _productRepository.AddProduct(productModel);
if (id > 0)
{
return RedirectToAction(nameof(AddNewProduct), new { isSuccess = true, prodId = id });
}
}
ViewBag.Categories = new SelectList(await _categoryRepository.GetAllCategories(), "CatID", "CategoryName");
return View();
}
private async Task<string> UploadImage(string folderPath, IFormFile file)
{
folderPath += Guid.NewGuid().ToString() + "_" + file.FileName;
string serverfolderpath = Path.Combine(_webHostEnvironment.WebRootPath, folderPath);
await file.CopyToAsync(new FileStream(serverfolderpath, FileMode.Create));
return "/" + folderPath;
}
public async Task<IActionResult> GetProductGallery(int id)
{
var data = await _productRepository.GetProductById(id);
return View(data);
}
public async Task<IActionResult> EditProductGallery (int id, bool isSuccess = false)
{
ViewBag.IsSuccess = isSuccess;
ViewBag.ProductID = id;
var ListOfProducts = await _productRepository.GetProductById(id);
ViewData["ProductGallery"] = ListOfProducts.ProductGallery;
return View(ListOfProducts);
}
public async Task<PartialViewResult> RenderProduct(int id)
{
var ListOfProducts = await _productRepository.GetProductById(id);
ViewData["ProductGallery"] = ListOfProducts.ProductGallery;
return PartialView(ListOfProducts);
}
public async Task<PartialViewResult> RenderProductGallery(int id)
{
var ListOfProducts = await _productRepository.getProductGallery(id);
ViewData["ProductId"] = ListOfProducts.ProductGallery;
return PartialView(ListOfProducts);
}
[HttpPost]
public async Task<IActionResult> EditProductGallery(ProductGalleryModel productGalleryModel)
{
if (ModelState.IsValid)
{
if (productGalleryModel.URL != null)
{
if (productGalleryModel.GalleryImages != null)
{
string fileName = Path.GetFileName(productGalleryModel.GalleryImages.ToString());
string filePath = Path.Combine(_webHostEnvironment.WebRootPath, fileName);
System.IO.File.Delete(filePath);
string folder = "images/product/cover/gallery/";
productGalleryModel.ProductGallery = new List<ProductGalleryModel>();
foreach (var file in productGalleryModel.GalleryImages)
{
var gallery = new ProductGalleryModel()
{
Name = file.FileName,
URL = await UploadImage(folder, file)
};
productGalleryModel.ProductGallery.Add(gallery);
}
await _productRepository.UpdateProductGallery(productGalleryModel.ID, productGalleryModel);
}
}
return RedirectToAction("GetAllProducts", new { isSuccess = true, ViewBag.ProductID });
}
return View();
}
}
}
ProductRepository for all get and edit methods
public class ProductRepository : IProductRepository
{
public async Task<ProductGalleryModel> getProductGallery(int id)
{
var result = await _prcContext.tblProductGalleries.Where(x => x.ProductsProductID == id).
Select(getgallerybyid => new ProductGalleryModel()
{
URL = getgallerybyid.URL,
}).FirstOrDefaultAsync();
return result;
}
public async Task<ProductModel> GetProductById(int id)
{
return await _prcContext.tblProducts.Where(x => x.ProductID == id).
Select(getproductbyId => new ProductModel()
{
ProductID = getproductbyId.ProductID,
ProductName = getproductbyId.ProductName,
ProductDesc = getproductbyId.ProductDesc,
Image1 = getproductbyId.Image1,
Image2 = getproductbyId.Image2,
Image3 = getproductbyId.Image3,
Image4 = getproductbyId.Image4,
OldPrice = getproductbyId.OldPrice,
NewPrice = getproductbyId.NewPrice,
Discount = getproductbyId.Discount,
CategoryId = getproductbyId.CategoryId,
ProductGallery = getproductbyId.productGallery.Select(g => new ProductGalleryModel()
{
ID = g.GalleryID,
ProductId = g.ProductsProductID,
Name = g.Name,
URL= g.URL
}).ToList()
}).FirstOrDefaultAsync();
}
public async Task<ProductModel> UpdateProduct(int id, ProductModel productModel)
{
var updateProduct = await _prcContext.tblProducts.FirstOrDefaultAsync(x => x.ProductID == id);
if (updateProduct != null)
{
updateProduct.ProductName = productModel.ProductName;
updateProduct.ProductDesc = productModel.ProductDesc;
updateProduct.Image1 = productModel.Image1;
updateProduct.Image2 = productModel.Image2;
updateProduct.Image3 = productModel.Image3;
updateProduct.Image4 = productModel.Image4;
updateProduct.OldPrice = productModel.OldPrice;
updateProduct.NewPrice = productModel.NewPrice;
updateProduct.Discount = productModel.Discount;
updateProduct.CategoryId = productModel.CategoryId;
}
await _prcContext.SaveChangesAsync();
return productModel;
}
public async Task<ProductGalleryModel> UpdateProductGallery(int id, ProductGalleryModel productGalleryModel)
{
var updateProductGallery = await _prcContext.tblProductGalleries.FirstOrDefaultAsync(x => x.ProductsProductID == id);
if (updateProductGallery != null)
{
var newproduct = new List<tblProductGallery>();
foreach (var gallery in newproduct)
{
updateProductGallery.URL = productGalleryModel.URL;
}
await _prcContext.SaveChangesAsync();
}
return productGalleryModel;
}
}
Edit Product Gallery View file
#model ProductGalleryModel
#{
ViewData["Title"] = "Edit Product Gallery";
Layout = "~/Areas/Admin/Views/Shared/_AdminLayout.cshtml";
}
<style>
.img-fluid {
width: 250px;
height: 250px;
}
</style>
<div class="">
<!-- Content Header (Page header) -->
<section class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-md-6">
<h1>Edit Product Gallery</h1>
</div>
<div class="col-md-6">
<ol class="breadcrumb float-md-right">
<li class="breadcrumb-item"><a asp-action="Index" asp-controller="Home">Home</a></li>
<li class="breadcrumb-item"><a asp-action="GetAllProducts" asp-controller="Product">Products</a></li>
<li class="breadcrumb-item active">Edit Product Gallery</li>
</ol>
</div>
</div>
</div><!-- /.container-fluid -->
</section>
<section class="content">
<div class="container-fluid">
<div class="card card-primary py-2">
<div class="card-header">
<h3 class="card-title">Existing Gallery</h3>
</div>
<div class="card-body">
<div class="row">
<input type="hidden" value="#ViewData["ProductGallery"]" />
<partial name="~/Areas/Admin/Views/RenderProduct.cshtml"
view-data="ViewData" />
</div>
</div>
</div>
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">Update Gallery</h3>
</div>
<form method="post" enctype="multipart/form-data" asp-action="EditProductGallery" asp-controller="Product">
<div class="card-body">
<div class="row">
<partial name="~/Areas/Admin/Views/RenderProductGallery.cshtml" view-data="ViewData" />
<div class="">
</div>
</div>
<div class="card-footer">
<input type="submit" value="Update" class="btn btn-success" />
</div>
</form>
</div>
</div>
</section>
</div>
#section Scripts
{
<script>
$(document).ready(function () {
$('.custom-file-input').on("change", function () {
var filename = $(this).val().split("\\").pop();
$(this).next('.custom-file-label').html(filename);
});
});
</script>
}
Product PartialView
#model ProductModel
<div class="col-sm-3">
<img src="#Model.Image1" class="img-fluid mb-2" alt="white sample" />
</div>
#for (int i = 0; i < Model.ProductGallery.Count(); i++)
{
<div class="col-sm-3">
<img src="#Model.ProductGallery[i].URL" class="img-fluid mb-2" alt="white sample" />
</div>
}
Product Gallery PartialView
model ProductGalleryModel
#{
ViewData["ProductGallery"] = true;
}
<div class="">
<input type="hidden" value="#Model.ProductId" />
#*<input type="hidden" value="#Model.ProductGallery" />*#
</div>
<div class="col-md-6">
<div class="form-group">
<label asp-for="GalleryImages"></label>
<div class="custom-file">
<input asp-for="GalleryImages" class="custom-file-input" id="inputGroupFile01">
<label class="custom-file-label" for="inputGroupFile01">Choose file</label>
</div>
<span asp-validation-for="GalleryImages" class="text-danger"></span>
</div>
</div>
#section Scripts
{
<script>
$(document).ready(function () {
$('.custom-file-input').on("change", function () {
var filename = $(this).val().split("\\").pop();
$(this).next('.custom-file-label').html(filename);
});
});
</script>
}
I am able to return the ProductPartialView with desired results but when i am calling the ProductGalleryPartialView then i am getting an Exception: The model item passed into the ViewDataDictionary is of type 'PRC_webapp.Areas.Admin.Models.ProductModel', but this ViewDataDictionary instance requires a model item of type 'PRC_webapp.Areas.Admin.Models.ProductGalleryModel'.
public IActionResult Index()
{
return View(_context.students);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(student student)
{
if (!ModelState.IsValid)
{
return View();
}
student.Image = await student.Photo.SaveFileAsync(_env.WebRootPath, "images");
await _context.students.AddAsync(student);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
public async Task<IActionResult> Update(int? id)
{
if (id == null)
{
return BadRequest();
}
var student = await _context.students.FindAsync(id);
if (student == null)
{
return NotFound();
}
return View(student);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Update(int? id, student newstudent)
{
if (id == null)
{
return BadRequest();
}
var oldstudent = _context.students.Find(id);
if (oldstudent == null)
{
return NotFound();
}
if (!ModelState.IsValid)
{
return View();
}
var path = Helper.GetPath(_env.WebRootPath, "img", oldstudent.Image);
if (System.IO.File.Exists(path))
{
System.IO.File.Delete(path);
}
newstudent.Image = await newstudent.Photo.SaveFileAsync(_environment.WebRootPath, "images");
oldstudent.Image = newstudent.Image;
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
public async Task<IActionResult> Delete(int id)
{
if (id == null)
{
return BadRequest();
}
var student = _context.students.Find(id);
if (student == null)
{
return NotFound();
}
var path = Helper.GetPath(_environment.WebRootPath, "img", student.Image);
if (System.IO.File.Exists(path))
{
System.IO.File.Delete(path);
}
_context.students.Remove(student);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}

LINQ Query return null value

when i use Linq query to fetching or compare data within DB it return me null value in morning it works right but now it not working it through exception.
model
public partial class CandidateRegistration
{
public int CandidateID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public bool RegisterAs { get; set; }
public Nullable<bool> ApprovedBit { get; set; }
}
public virtual DbSet<CandidateRegistration> CandidateRegistrations { get; set; }
Controller
public ActionResult Login(string emaillogin, string passwordslogin, bool registerAs, string Rememberme)
{
bool aprovedbitforemployer = false;
if (registerAs == true)
{
var checkApprovedBitForEmployer = DB.EmployerRegistrations.FirstOrDefault(e => e.Email == obj.Email);
aprovedbitforemployer = Convert.ToBoolean((checkApprovedBitForEmployer.ApprovedBit));
if (aprovedbitforemployer != false)
{
if(checkApprovedBitForEmployer.Email == emaillogin && checkApprovedBitForEmployer.Passwords == passwordslogin)
{
Session["Username"] = checkApprovedBitForEmployer.Email.ToString();
Session["Passwords"] = checkApprovedBitForEmployer.Passwords.ToString();
Session["Employee"] = "Employer";
}
}
else
{
TempData["Notpermission"] = "Your account is in activation process please wait...";
}
}
else if (registerAs == false)
{
CandidateRegistration checkApprovedBitForEmplloyee = DB.CandidateRegistrations.FirstOrDefault(c => c.Email == emaillogin);
aprovedbitforemployer = Convert.ToBoolean((checkApprovedBitForEmplloyee.ApprovedBit));
if(aprovedbitforemployer == true)
{
if (checkApprovedBitForEmplloyee.Email == emaillogin && checkApprovedBitForEmplloyee.Password == passwordslogin)
{
Session["Username"] = checkApprovedBitForEmplloyee.Email.ToString();
Session["Passwords"] = checkApprovedBitForEmplloyee.Password.ToString();
Session["Employee"] = "Employee";
}
}
else
{
TempData["Notpermission"] = "Your account is in activation process please wait...";
}
}
else
{
TempData["Emailorpasswordmistakes"] = "Email or password incorrect";
}
return View();
}
"checkApprovedBitForEmployer" return null value it=n this variable.
View
#using (Html.BeginForm("Login", "Home", FormMethod.Post))
{
<div class="col-md-6 account">
<h3>Login</h3>
<span id="Emessage" onshow="show();"> #TempData["Notpermission"] </span>
<label for="">Username or email address *</label>
<div class="form-group">
<input type="email" name="emaillogin" id="emaillogin" class="form-control input-sm " placeholder="Email Address" style="width:70%; height: 35px; text-transform:none;">
</div>
<label for="">Password *</label>
<div class="form-group">
<input type="password" name="passwordslogin" id="passwordslogin" class="form-control input-sm" placeholder="Password" style="width:70%; height: 35px; text-transform:none; ">
<span id="Emessage" onshow="show();" >#TempData["Emailorpasswordmistakes"]</span>
</div>
<div class="form-group">
#Html.DropDownList("RegisterAs", new List<SelectListItem>()
{
new SelectListItem() { Text= "Register As", Selected = true },
new SelectListItem() { Text= "Employer", Value = "true" },
new SelectListItem() { Text= "Employee", Value = "false" }
}, new { htmlAttributes = new { #class = "form-control" } })
</div>
<button>Login</button>
<input type="checkbox" id="rememberme" name="Rememberme" value="forever"><span>Remember me</span>
<br />
Lost your Password
</div>
}
i am using html form and i want to use this but only tell me why it not fetch data from database.
var checkApprovedBitForEmployer = DB.EmployerRegistrations.FirstOrDefault(e => e.Email == obj.Email);
In above line you are checking email address from database with Obj.Email.i guess you need to compare with emaillogin.

MVC save image to DB (with EF)

I am still new to MVC and am struggling with uploading an image to a DB in my web application. I've seen tons of articles on the subject, followed instructions but still I am stuck with the following error message:
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
Whenever I use [Bind(Exclude = "CompetitionPicture")], everything would work fine, except for, of course, the "CompetitionPicture" won't be included.
My ViewModel looks as follows:
public class PhotoCompetition
{
public int ID { get; set; }
public string UserID { get; set; }
public string FirstName { get; set; }
public string Email { get; set; }
public byte[] CompetitionPicture { get; set; }
[Required]
[Display(Name = "by checking this box I accept the Terms & Conditions")]
public bool TermsAndConditionsAccepted { get; set; }
public DateTime TimeStamp { get; set; }
}
Controller is as follows:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UploadCompetitionPicture(/*[Bind(Exclude = "CompetitionPicture")]*/ PhotoCompetition model)
{
string test = Request.Form["CompetitionPicture"];
byte[] bt = Convert.FromBase64String(test.Split(',')[1]);
var participation = new PhotoCompetition
{
CompetitionPicture = bt
};
// var participation = new PhotoCompetition
// {
// UserID = User.Identity.GetUserId(),
// Email = User.Identity.GetUserName(),
// TermsAndConditionsAccepted = model.TermsAndConditionsAccepted,
// TimeStamp = DateTime.UtcNow.ToUniversalTime()
// };
// participation.CompetitionPicture = competitionPicture;
// DB.PhotoCompetition.Add(model);
// DB.SaveChanges();
// return RedirectToAction("Index");
//}
return View(model);
}
and the View:
<section id="photoCompetition" class="manageForm">
#using (Html.BeginForm("UploadCompetitionPicture", "errandom", FormMethod.Post, new { #id = "photoCompetitionForm", #class = "form-horizontal", #role = "form", #enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div id="photoCompetitionSection" class="manageSection">
<p id="photoCompetitionSectionTitle" class="manageSectionTitle">
Upload your picture and be selected as our model!
</p>
#Html.HiddenFor(m => m.UserID)
#Html.HiddenFor(m => m.Email)
#Html.HiddenFor(m => m.FirstName)
#Html.HiddenFor(m => m.TimeStamp)
<div id="photoCompetitionProfilePictureArea" class="manageArea row">
#Html.LabelFor(m => m.CompetitionPicture, new { #id = "photoCompetitionProfilePictureLabel", #class = "manageLabel col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-1 col-md-3 col-lg-offset-1 col-lg-4" })
<a id="photoCompetitionProfilePictureSelectionButton" class="manageField col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset0 col-md-7 col-lg-offset-0 col-lg-6" href="#">
select a file...
</a>
#Html.TextBoxFor(m => m.CompetitionPicture, new { #id = "photoCompetitionProfilePictureField", #class = "manageField col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-0 col-md-7 col-lg-offset-0 col-lg-6", #name = "CompetitionPicture", #type = "file", #style = "display: none" })
</div>
<div id="photoCompetitionTermsAndConditionsArea" class="manageArea row">
#Html.CheckBoxFor(m => m.TermsAndConditionsAccepted, new { #id = "photoCompetitionTermsAndConditionsField", #class = "photoCompetitionTermsAndConditionsField" })
#Html.LabelFor(m => m.TermsAndConditionsAccepted, new { #id = "photoCompetitionTermsAndConditionsLabel", #class = "photoCompetitionTermsAndConditionsLabel" })
</div>
<script>
jQuery("#photoCompetitionProfilePictureSelectionButton").click(function () {
$("#photoCompetitionProfilePictureField").click();
});
</script>
<script>
$("#photoCompetitionProfilePictureField").change(function () {
var fullFileName = $("#photoCompetitionProfilePictureField").val()
$("#photoCompetitionProfilePictureSelectionButton").html(fullFileName.substr(fullFileName.lastIndexOf('\\') + 1));
});
</script>
<div id="photoCompetitionButtonArea" class="manageArea row">
<input id="photoCompetitionButtonUpload" class="manageButton col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-1 col-md-10 col-lg-offset-1 col-lg-10" type="submit" value="Save" />
</div>
</div>
}
</section>
Your support is highly appreciated!
I'm stuck in this issue for days before, i will put simple solving.
first: I save image path as string in DB not byte
and Image File as HttpPostedFileBase in model Like :`
public string ProductImage { get; set; }
[Required(ErrorMessage = "Image is required")]
public HttpPostedFileBase ImageFile { get; set; }
in view you will write :
<div class="form-group">
<div class="col-md-10">
<input type="file" name="ImageFile" required />
</div>
#Html.ValidationMessageFor(model => model.ImageFile, "", new { #class = "text-danger" })
</div>
name of input must be like the name in model and here I named it ImageFile
in controller will write
public void SaveImage(Product pro)
{
string fileName = Path.GetFileNameWithoutExtension(pro.ImageFile.FileName);
string exetention = Path.GetExtension(pro.ImageFile.FileName);
fileName = fileName + DateTime.Now.ToString("yymmssfff") + exetention;
pro.ProductImage = "~/ProductDropBox/" + fileName;
fileName = Path.Combine(Server.MapPath("~/ProductDropBox/"), fileName);
pro.ImageFile.SaveAs(fileName);
}
I use this function to save image in DB and in Folder created for images
finally in action result you will write :
public ActionResult AddProducts(Product pro)
{
if (ModelState.IsValid)
{
SetCategories();
SaveImage(pro);
pro.UPID = Guid.NewGuid();
using (db)
{
db.Products.Add(pro);
db.SaveChanges();
}
return RedirectToAction("Index");
}
else
{
return View("AddProducts",pro);
}
}
I hope this useful

knockout.js binding issue when trying to refresh data

I am using knockout.js data binding. At the page load the binding works fine and data is shown on the page correctly. Then I try to push data back to the database and the push is successful. The database receives the data OK.
The problem comes when I try to reload the data upon push success. At this time the binding already happen once (at the page load). If I don't bind it again the data on the page does not refresh. If I do the binding again knockout.js issues an error "cannot bind multiple times". If I do a cleanup before rebinding I receive an error "nodeType undefined".
Can anyone tell me what I have missed here? I am using ASP.NET MVC 4.0 with knockout.js 3.0.0.
Controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplJSON.Controllers
{
public class KnockoutController : Controller
{
//
// GET: /Knockout/
public ActionResult Index()
{
return View();
}
[HttpGet]
public JsonResult GetProductList()
{
var model = new List<Product>();
try
{
using (var db = new KOEntities())
{
var product = from p in db.Products orderby p.Name select p;
model = product.ToList();
}
}
catch (Exception ex)
{ throw ex; }
return Json(model, JsonRequestBehavior.AllowGet);
}
// your controller action should return a JsonResult. There's no such thing as a controller action that returns void. You have specified dataType: 'json' so return JSON. That's it. As far as what parameter this controller action should take, well, from the JSON you are sending ({"Name":"AA"}) it should be a class that has a Name property of type string.
// modify your action signature to look like this: [HttpPost] public ActionResult SaveProduct (Product product) { ... return Json(new { success = true }); }. Or get rid of this dataType: 'json' attribute from your AJAX request if you don't want to return JSON. In this case you could return simply status code 201 (Created with empty response body): return new HttpStatusCodeResult(201);.
[HttpPost]
public ActionResult SaveProduct(Product product)
{
using (var db = new KOEntities())
{
db.Products.Add(new Product { Name = product.Name, DateCreated = DateTime.Now });
db.SaveChanges();
}
return Json(new { success = true });
}
}
}
View:
#{
ViewBag.Title = "Knockout";
}
<h2>Knockout</h2>
<h3>Load JSON Data</h3>
<div id="loadJson-custom" class="left message-info">
<h4>Products</h4>
<div id="accordion" data-bind='template: { name: "product-template", foreach: product }'>
</div>
</div>
<h3>Post JSON Data</h3>
<div id="postJjson-custom" class="left message-info">
<h4>Add Product</h4>
<input id="productName" /><br />
<button id="addProduct">Add</button>
</div>
#section Scripts {
#Scripts.Render("~/bundles/knockout")
#Scripts.Render("~/bundles/livequery")
<script src="/Scripts/jquery.livequery.min.js"></script>
<style>
#accordion { width: 400px; }
</style>
<script id="product-template" type="text/html">
<h3><a data-bind="attr: {href:'#', title: Name, class: 'product'}"><span data-bind="text: Name"></span></a></h3>
<div>
<p>Here's some into about <span data-bind="text: Name" style="font-weight: bold;"></span> </p>
</div>
</script>
<script>
var isBound;
function loadJsonData() {
$.ajax({
url: "/knockout/GetProductList",
type: "GET",
contentType: "application/json",
dataType: "json",
data: {},
async: true,
success: function (data) {
var loadJsonViewModel = {
product: ko.observableArray(),
init: function () {
loadAccordion();
}
};
var a = $('loadJson-custom');
loadJsonViewModel.product = ko.mapping.fromJS(data);
if (isBound) { }
else
{
ko.applyBindings(loadJsonViewModel, $('loadJson-custom')[0]);
isBound = true;
}
loadJsonViewModel.init();
}
});
}
// push data back to the database
function pushJsonData(productName) {
var jData = '{"Name": "' + productName + '"}';
$.ajax({
url: "/knockout/SaveProduct",
type: "POST",
contentType: "application/json",
dataType: "json",
data: jData,
async: true,
success: function (data, textStatus, jqXHR) {
console.log(textStatus + " in pushJsonData: " + data + " " + jqXHR);
//ko.cleanNode($('loadJson-custom')[0]);
loadJsonData();
},
error: function (jqXHR, textStatus, errorThrown) {
alert(textStatus + " in pushJsonData: " + errorThrown + " " + jqXHR);
}
});
}
function loadAccordion() {
$("#accordion > div").livequery(function () {
if (typeof $("#accordion").data("ui-accordion") == "undefined")
{
$("#accordion").accordion({ event: "mouseover" });
}
else
{
$("#accordion").accordion("destroy").accordion({ event: "mouseover" });
}
});
}
$(function () {
isBound = false;
loadJsonData();
$("#addProduct").click(function () {
pushJsonData($("#productName").val());
});
});
</script>
}
Here is a complete solution for your question.
I have just implemented and checked.
Please have a look.
I have created a class for getting some records ie: Records.cs.
public static class Records
{
public static IList<Student> Stud(int size)
{
IList<Student> stud = new List<Student>();
for (int i = 0; i < size; i++)
{
Student stu = new Student()
{
Name = "Name " + i,
Age = 20 + i
};
stud.Add(stu);
}
return stud;
}
}
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
}
Here is a controller for the respective view.
//
// GET: /HelpStack/
private static IList<Student> stud = Records.Stud(10);
public ActionResult HelpStactIndex()
{
return View();
}
[HttpGet]
public JsonResult GetRecord()
{
return Json(stud, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public void PostData(Student model)
{
//do the required code here as All data is in "model"
}
Here is a view as HTML, I have taken two section one for list and other to Add records
<div id="loadJson-custom">
<h4>Student</h4>
<table width="100%">
<tr>
<td style="width: 50%">
<div id="accordion" data-bind='template: { name: "product-template", foreach: Student }'>
</div>
</td>
<td valign="top">
<div id="NewStudent">
<input type="text" data-bind="value: Name" /><br />
<input type="number" data-bind="value: Age" /><br />
<input type="submit" data-bind="click: Save" value="AddNew" />
</div>
</td>
</tr>
</table>
Here is your scripts for Knockoutjs.
<script id="product-template" type="text/html">
<h3><a data-bind="attr: { href: '#', title: Name, class: 'product' }"><span data-bind=" text: Name"></span></a>
<br />
Age: <span data-bind="text: Age"></span>
</h3>
<div>
<p>Here's some into about <span data-bind="text: Name" style="font-weight: bold;"></span></p>
</div>
</script>
<script type="text/javascript">
//Model for insert new record
var Model = {
Name: ko.observable(''),
Age: ko.observable(''),
};
var Student = ko.observableArray([]); // List of Students
function loadData() { //Get records
$.getJSON("/HelpStack/GetRecord", function (data) {
$.each(data, function (index, item) {
Student.push(item);
});
}, null);
}
function Save() { //Save records
$.post("/HelpStack/PostData", Model, function () { //Oncomplete i have just pushed the new record.
// Here you can also recall the LoadData() to reload all the records
//Student.push(Model);
Student.unshift(Model); // unshift , add new item at top
});
}
$(function () {
loadData();
ko.applyBindings(Model, $('#NewStudent')[0]);
});
</script>
You are declaring your model inside loadJsonData function success callback, & creating new object on every success callback, move the model outside that function, create an object & use it inside loadJsonData function, it will fix the issue.