MVC Controller gets NULL Exception - asp.net

I am using ASP.NET Core and AngularJS (not AngularJS 2). I followed this link AngularJS Tutorial for Login with MVC but my mvc controller (AuthenticateUser) gets null value. Though I am getting this value through my script
JSON:
Password: "test"
UserName: "test"
Source:
{"UserName":"test","Password":"test"}
And though I append [FromBody], the controller (AuthenticateUser) still gets null value.
Here is my code:
Service.js
app.service("myAppService", function ($http) {
this.UserLogin = function (User) {
var response = $http({
method: "post",
url: "../Administrator/AuthenticateUser",
data: JSON.stringify(User),
dataType: "json"
});
return response;
}
});
Controller.js
app.controller("MyAppController", function ($scope, MyAppService) {
$scope.LoginCheck = function () {
var User = {
UserName: $scope.usrName,
Password: $scope.usrPassword
};
var getData = MyAppService.UserLogin(User);
getData.then(function (d) {
alert(d.UserName);
});
debugger;
}
});
Index.cshtml
<div class="container">
<div id="loginbox" style="margin-top:50px;" class="mainbox col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2">
<div class="panel panel-info">
<div class="panel-heading">
<div class="panel-title">Sign In</div>
<div style="float:right; font-size: 80%; position: relative; top:-10px">Forgot password?</div>
</div>
<div style="padding-top:30px" class="panel-body">
<div style="display:none" id="login-alert" class="alert alert-danger col-sm-12"></div>
<form id="loginform" class="form-horizontal" role="form">
<div style="margin-bottom: 25px" class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input type="text" class="form-control" ng-model="usrName" placeholder="Username">
</div>
<div style="margin-bottom: 25px" class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input type="password" class="form-control" ng-model="usrPassword" placeholder="Password">
</div>
<div style="margin-top:10px" class="form-group">
<!-- Button -->
<div class="col-sm-12 controls">
<button type="button" class="btn btn-success" ng-click="LoginCheck();">Login</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
AdministratorController.cs
public class AdministratorController : Controller
{
private TestDBOnlineContext _context;
// GET: /<controller>/
public IActionResult Index()
{
return View();
}
[HttpPost]
public JsonResult AuthenticateUser(UserAccessViewModel _users)
//public string AuthenticateUser(UserAccessViewModel userAccess)
{
//string msg = string.Empty;
//if (userAccess.UserName == null || userAccess.UserPassword == null)
// return "Please fill-out all entries";
//else
//{
var users = _context.UserAccess.Where(w => w.Username.Equals(_users.UserName) &&
w.Userpassword.Equals(_users.UserPassword));
// if (users != null)
// return "Thanks for logging.";
// else
// return "Invalid username or password.";
//}
return Json(users);
}
}
Hope that you can help me on this. I stuck for many days already. Thanks in advance.

Related

How to import parameters from post method

How do I get the get method called aidx parameter by post method?
When I start with the current code, it says that it is not defined.
aidx is the primary key, and I want to assign that primary key to the Family column.
<div id="blogpost" class="inner-content">
<form id="formdata"action="#Url.Action("Detail", "Board")" method="post" enctype="multipart/form-data">
<section class="inner-section">
<div class="main_blog text-center roomy-100">
<div class="col-sm-8 col-sm-offset-2">
<div class="head_title text-center">
<h2>#Html.DisplayTextFor(m => m.Article.Title)</h2>
#Html.HiddenFor(m => m.Article.ArticleIDX)
<div class="separator_auto"></div>
<div class="row">
<div class="col-md-8" style="margin-left:6%;">
<p>
<label>분 류 : </label>
#Html.DisplayTextFor(m => m.Article.Category)
</p>
</div>
<div class="col-md-8" style="margin-left:5%;">
<p>
<label>작성자 : </label>
#Html.DisplayTextFor(m => m.Article.Members.Name)
</p>
</div>
<div class="col-md-8" style="margin-left:10.6%;">
<p>
<label>작성일 : </label>
#Html.DisplayTextFor(m => m.Article.ModifyDate)
</p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<p>
<label style="font-size:x-large;">문의내용</label>
<br />
<br />
#Html.DisplayTextFor(m => m.Article.Contents)
<br />
<br />
<br />
<br />
</p>
</div>
</div>
<div class="dividewhite2"></div>
<p>
#if (User.Identity.IsAuthenticated == true)
{
<button type="button" class="btn btn-sm btn-lgr-str" onclick="btnEdit()">수정하기</button>
<button type="button" class="btn btn-sm btn-lgr-str" onclick="btnReply()">답글달기</button>
}
<button type="button" class="btn btn-sm btn-lgr-str" onclick="javascript:history.go(-1);">목록이동</button>
<br />
<br />
<br />
<br />
</p>
<div>
#Html.Partial("_Comment", new ViewDataDictionary { { "id", Model.Article.ArticleIDX } })
#Html.Partial("_CommentView", new ViewDataDictionary { { "CommentIDX", ViewBag.CommentIDX }, { "idx", Model.Article.ArticleIDX } })
</div>
</div>
</div>
<div class="dividewhite8"></div>
</section>
</form>
<script >
function btnEdit() {
if (#User.Identity.Name.Equals(Model.Article.Members.ID).ToString().ToLower() == true)
{
location.replace("/Board/Edit?aidx=#Model.Article.ArticleIDX");
}
else
{
alert("권한이 없습니다.");
}
}
function btnReply() {
location.replace("ReplyCreate?aidx=#Model.Article.ArticleIDX");
}
[HttpGet]
public ActionResult ReplyCreate(int aidx)
{
Articles articleReply = new Articles();
return View(articleReply);
}
[HttpPost]
public ActionResult ReplyCreate(Articles replyArticles, int aidx)
{
try
{
replyArticles.Family = aidx;
replyArticles.ModifyDate = DateTime.Now;
replyArticles.ModifyMemberID = User.Identity.Name;
db.Articles.Add(replyArticles);
db.SaveChanges();
ViewBag.Result = "OK";
}
catch (Exception ex)
{
ViewBag.Result = "FAIL";
}
return View(replyArticles);
}
You have several problem in your HTML and JavaScript:
You're not submitting anything, you're redirecting the page in JavaScript.
You're hiding the button if the user is not authenticated, but everybody can see, copy, and run the URL from your JavaScript.
Even if you fix #1 and your ReplyCreate() action gets called, it's expecting 2 parameters, but you're only sending one (aidx). The other parameter (replyArticles) will be always null.
Your code is vulnerable to CSRF attack.
To fix #1, you can add the parameter to your form instead of JavaScript, and change your button's type to submit:
<form id="formdata"
action="#Url.Action("Detail", "Board", null, new { aidx = Model.Article.ArticleIDX })"
method="post" enctype="multipart/form-data">
<div class="dividewhite2"></div>
<p><button type="submit" class="btn btn-sm btn-lgr-str">답글달기</button></p>
</form>
Or you can use a hidden field.
To fix #2, move the check outside the form and delete your JavaScript:
#if (User.Identity.IsAuthenticated) {
<form id="formdata"
action="#Url.Action("Detail", "Board", null, new { aidx = Model.Article.ArticleIDX })"
method="post" enctype="multipart/form-data">
<div class="dividewhite2"></div>
<p><button type="submit" class="btn btn-sm btn-lgr-str">답글달기</button></p>
</form>
}
To fix #3, you'll have to add the replyArticles parameter to your form or as a hidden field.
To fix #4, you'll need to add the forgery check to your form and your action.

Validate two depending dates

I have two date values, that I need to validate. This validaton is compound: One date needs to be sooner than the other (think StartingDate and FinishDate).
How can I validate for this?
Based on this post, which seems to pose a similar situation, one recomendation is to use MVC Foolproof Validation. Is this still the best option? Is there other way to validate such task?
My code in the view, if it helps:
<div class="row">
<div class="col-md-3">
<div class="row">
<div class="col-md-5">
<span class="glyphicon glyphicon-calendar" aria-hidden="true"></span>
<span style="font-size:large;">Início </span>
</div>
<div class="col-md-7">
#Html.EditorFor(model => model.Inicio, new { htmlAttributes = new { #class = "form-control datetimepicker" } })
</div>
</div>
</div>
<div class="col-md-3">
<div class="row">
<div class="col-md-5">
<span class="glyphicon glyphicon-calendar" aria-hidden="true"></span>
<span style="font-size:large;">Fim </span>
</div>
<div class="col-md-7">
#Html.EditorFor(model => model.Fim, new { htmlAttributes = new { #class = "form-control datetimepicker" } })
</div>
</div>
</div>
</div>
<script>
<!--jQuery DateTimePicker-->
jQuery('.datetimepicker').datetimepicker({
format: 'd/m/Y H:i'
});
</script>
I don't see why a simple JS solution can't help here, so here it is:
HTML:
<p>Start Date: <input type="text" id="datepicker1"></p>
<p>End Date: <input type="text" id="datepicker2"></p>
<button id="TestCondition">
Click Me!
</button>
JS:
$(function() {
$("#datepicker1").datepicker();
});
$(function() {
$("#datepicker2").datepicker();
});
$("#TestCondition").click(function(){
alert($("#datepicker1").val());
alert($("#datepicker2").val());
if($("#datepicker2").val() < $("#datepicker1").val()){
alert("End Date must come after Start Date!");
}
});
Here is a fiddle for that: JSFiddle
Alternate Solution using Controller in MVC
Once you submit this page to the controller, you can do a check like so (C#):
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult NameOfAction(ViewModel nameOfViewModel)
{
if(nameofViewModel.FinishDate <= nameofViewModel.StartDate)
{
ModelState.AddModelError("FinishDate", "Finish Date needs to be after the Start Date!");
return View(nameOfViewModel);
}
}
Let me know if this helps, or if anything needs to be changed.
Based on BviLLe_Kid answer, which I accept, here's what I ended up doing:
if (ModelState.IsValid)
{
if (nameofViewModel.FinishDate <= nameofViewModel.StartDate)
{
ModelState.AddModelError(string.Empty, "Error message here");
return View(nameofViewModel);
}
else {
//code for when validation is OK
}
}
In the view:
<div style="color:red;">
#Html.ValidationSummary(true)
#Html.ValidationMessageFor(model => model.FinishDate)
</div>

trumbowyg editor with vuejs

I am using the trumbowyg editor control in my vuejs spa. From the documentation I know that I can use the following code to set the contents of the editor.
$('#editor').trumbowyg('html','<p>Your content here</p>');
$('#editor').trigger('tbwchange');
However, it is not working for me in my VueJs App. I have an object that has a description key defined. I can console.log the description , but when I try to assign it to the editor control as mentioned above, it fails . I can see no error in the console but the text just won't show up in the editor.
Here is what I am going at the moment.
<template>
<div class="modal fade" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
<span v-if="anouncement">Edit Anouncement</span>
<span v-else>New Anouncement</span>
</h4>
</div>
<div class="modal-body">
<div class="form-group">
<input type="text" placeholder="enter anouncement summary here" class="form-control" v-model="anouncementObj.summary">
</div>
<div class="form-group">
<input type="text" placeholder="enter location here" class="form-control" v-model="anouncementObj.location">
</div>
<textarea class="note-view__body" id="anonDescription" v-model="description" placeholder="enter event description"></textarea>
</div>
<div class="modal-footer">
<button type="button" v-on:click="clear()" class="btn btn-link" data-dismiss="modal">Close</button>
<button type="button" v-on:click="performSave()" class="btn btn-link">Save</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props : {
anouncement : Object
},
data() {
return {
anouncementObj :{}
}
},
mounted () {
this.makeTextBoxReady();
this.anouncementObj = Object.assign({},this.anouncementObj, this.anouncement || {});
$('#anonDescription').trumbowyg('html',this.anouncement.description);
$('#anonDescription').trigger('tbwchange');
console.log(this.anouncement.description);
},
methods : {
makeTextBoxReady: function() {
$(document).ready(function() {
if (!$('html').is('.ie9')) {
if ($('.note-view__body')[0]) {
$('.note-view__body').trumbowyg({
autogrow: true,
btns: [
'btnGrp-semantic', ['formatting'],
'btnGrp-justify',
'btnGrp-lists', ['removeformat']
]
});
}
}
});
},
performSave : function() {
let description = $('#anonDescription').trumbowyg('html');
let formData = new FormData();
for (name in this.anouncementObj) {
formData.append(name, this.anouncementObj[name]);
}
if( !this.anouncementObj.id) {
this.anouncementObj.id = 0;
}
formData.append('description',description);
this.$http.post('/admin/anouncement/createOrUpdate', formData).then(response => {
// console.log(response);
if(response.data.status==200) {
alert(response.data.message);
this.$emit('getAnouncements');
}
})
},
clear: function() {
this.anouncementObj= {};
}
}
}
</script>
Can you please let me know what I am doing wrong here? I have also tried the nexttick approach but even that is not working.
I got it working. I was not using the correct bootstrap modal id. Please see this related question for more information.
This is the correct code.
if(this.anouncementObj && this.anouncementObj.description && this.anouncementObj.id) {
$('#'+this.anouncementObj.id+' #anonDescription').trumbowyg('html',this.anouncementObj.description);
$('#'+this.anouncementObj.id+' #anonDescription').trigger('tbwchange');
}

My UI does not reflect changes to my Model [duplicate]

This question already has answers here:
MVC 3 - Html.EditorFor seems to cache old values after $.ajax call
(5 answers)
Closed 6 years ago.
I have a ASP MVC web app.
I have a partial form and it initally displays 'Hello Andy!'.
I press the submit button and I change this to 'Hello Andy Again!.
I pass the model back to the UI.
The label still shows the old value.
Why?
My markup:
#using (Ajax.BeginForm("SaveAlertPreferences", "Users", new AjaxOptions
{
UpdateTargetId = "partialform",
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
{
<div>
#Html.AntiForgeryToken()
<div class="section group">
<div class="col span_3_of_12">
#Html.LabelFor(model => model.myStub)
</div>
<div class="col span_9_of_12">
#Html.TextBoxFor(model => model.myStub)
</div>
</div>
<div class="section group">
<div class="col span_3_of_12">
</div>
<div class="col span_4_of_12">
<input type="submit" value="Press me" />
</div>
<div class="col span_5_of_12">
</div>
</div>
</div>
}
My Model:
public class ChangeAlertPreferencesModel
{
public string myStub { get; set; }
}
My Controller:
[AcceptVerbs("HEAD", "GET")]
public PartialViewResult _ChangeAlertPreferences()
{
Response.CacheControl = "no-cache";
ChangeAlertPreferencesModel m = new ChangeAlertPreferencesModel();
m.myStub = "Hello Andy!";
return PartialView("_ChangeAlertPreferences", m);
}
[HttpPost]
public PartialViewResult SaveAlertPreferences(ChangeAlertPreferencesModel m)
{
Response.CacheControl = "no-cache";
if (ModelState.IsValid)
{
m.myStub = "Hello Andy Again!";
return PartialView("_ChangeAlertPreferences", m);
}
else
{
m.myStub = "I have errored!";
return PartialView("_ChangeAlertPreferences", m);
}
return null;
}
To complete my comment, your form statement looks odd,so you might wanna try this:
#using (Ajax.BeginForm("SaveAlertPreferences", "Users", new AjaxOptions
{
UpdateTargetId = "partialform",
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
}))
{
#Html.AntiForgeryToken()
<div class="section group">
<div class="col span_3_of_12">
#Html.LabelFor(model => model.myStub)
</div>
<div class="col span_9_of_12">
#Html.TextBoxFor(model => model.myStub)
</div>
</div>
<div class="section group">
<div class="col span_3_of_12">
</div>
<div class="col span_4_of_12">
<input type="submit" value="Press me" />
</div>
<div class="col span_5_of_12">
</div>
</div>
}
To explain, in the first line, the using part declares the form and how it should behave, then you end(close) that declaration and open the block that should contain the body of the form.

Page returns 404 error on submit using angular grid and asp.mvc

When I click submit button, I am getting a 404 error, page cannot be found.
I am using angular-ui-grid with ASP.MVC to return a list of pdfs from a Sql Server database. On the page's initial load, the grid is populated with all the pdfs and are paginated. I have added some input fields to the page so that after the initial load, you can then search by name and date range. When the button is clicked, the page returns a 404 error, cannot be found.
View
#model WSCWebsite.Models.SC_Opinions_Search_Result
#using (Html.BeginForm("Opinions", "Home", FormMethod.Post, new {#class = "form-horizontal", #id = "searchForm"}))
{
<p>Enter search information into one or more of the fields below.</p>
<p>Using more than one field will result in a more narrow search.</p>
<p>Opinions and orders published prior to 2006 are not available in this search.</p>
<div class="well" ng-controller="OpinionDefaultData">
<div class="form-group">
<label class="control-label col-sm-3">Start Date</label>
<div class="col-sm-5">
<input type="text" ng-model="StartDate" class="datefield" />
<span style="padding: 0 0 0 3px">example: 2/27/2006</span>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-3">End Date</label>
<div class="col-sm-5">
<input type="text" ng-model="EndDate" class="datefield" />
<span style="padding: 0 0 0 3px">example: 12/27/2014</span>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-3">Appellant</label>
<div class="col-sm-5">
<input type="text" ng-model="Appellant" />
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-3">Appellee</label>
<div class="col-sm-5">
<input type="text" ng-model="Appellee" />
</div>
</div>
#*<div class="form-group">
<label class="control-label col-sm-3">Docket Number</label>
<div class="col-sm-5">
<div>
#Html.TextBoxFor(m => m.DocketNumber, new { #class = "form-control", #style="display:inline-block; width:220px" })
<span style="padding: 0 0 0 3px">example: 12/27/2014</span>
</div>
</div>
</div>*#
<div class="form-group">
<div class="col-sm-4"></div>
<div class="col-sm-2">
<input type="button" value="Clear Form" onclick="history.go(0)" class="btn btn-primary" />
</div>
<div class="col-sm-2">
<button ng-click="SearchOpinions()" class="btn btn-primary">Search</button>
</div>
</div>
</div>
MVC Controller
[HttpGet]
public JsonResult GetOpinions(DateTime? StartDate, DateTime? EndDate, string Appellant, string Appellee, string DocketNumber)
{
if (EndDate != null)
{
EndDate = EndDate.Value.AddHours(23);
}
OpinionEntities dbContext = new WSCWebsite.Models.OpinionEntities();
var lst = dbContext.SC_Opinions_Search(DocketNumber,Appellant, Appellee, StartDate, EndDate, 200).ToList();
return Json(lst, JsonRequestBehavior.AllowGet);
}
Angular Controller
var app = angular.module('WSCWebSite', ['angularUtils.directives.dirPagination']);
app.controller("OpinionDefaultData", function ($scope, $http) {
$scope.StartDate = "";
$scope.EndDate = "";
$scope.Appellant = "";
$scope.Appellee = "";
$scope.DocketNumber = "";
$scope.SearchOpinions = function () {
$scope.Opinions = []; //declare an empty array
$http.get("/Home/GetOpinions", {
params: {
StartDate: $scope.StartDate,
EndDate: $scope.EndDate,
Appellant: $scope.Appellant,
Appellee: $scope.Appellee,
DocketNumber: $scope.DocketNumber
}
}).success(function (response) {
$scope.Opinions = response;
});
}
});
app.controller('OpinionData', function ($scope, $http) {
$scope.Opinions = []; //declare an empty array
$http.get("/Home/GetOpinions", {
params: {
StartDate: $scope.StartDate
, EndDate: $scope.EndDate
, Appellant: $scope.Appellant
, Appellee: $scope.Appellee
, DocketNumber: $scope.DocketNumber
}
}).success(function (response) {
$scope.Opinions = response; //ajax request to fetch data into $scope.data
});
});
your form is posting here,
#using (Html.BeginForm("Opinions", "Home", FormMethod.Post, new {#class = "form-horizontal", #id = "searchForm"}))
{
}
look here you have passed Opinions, as action but your action name is GetOpinions()
look on it, maybe it will help you..

Resources