I have a question about .Net MVC, because Visual Studio shows me the application server error in the following form?
Server error in application '/'. The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its
dependencies) may have been removed, renamed, or temporarily
unavailable. Please review the URL below and make sure it is spelled
correctly.
Requested URL: / Register
<form action="Account/Registra" method="post">
<input class="form-control" type="number" name="id" value="" placeholder="Id" required/>
<input class="form-control" type="text" name="nombre" value="" placeholder="Nombre" required/>
<input class="form-control" type="text" name="correo" value="" placeholder="Correo" required/>
<input class="form-control" type="password" name="contrasena" value="" placeholder="Contraseña"/>
<input class="form-control" type="text" name="direccion" value="" placeholder="Direccion" required/>
<input class="form-control btn btn-primary" type="submit" name="btn" value="Registrar" />
</form>
And this one that has the same action text "controller / action" but does this work correctly for me.
<form action="Account/Validar" method="get">
<input type="text" name="correo" value="" placeholder="Correo" required class="form-control"/>
<input type="password" name="contrasena" value="" placeholder="Contraseña" required class="form-control"/>
<input type="submit" name="btn" value="Ingresar" class="btn btn-primary form-control"/>
</form>
They both have their respective existing methods and views. Any solution or opinion about this error?
public ActionResult Registra()
{
return View();
}
[HttpPost]
public ActionResult Registra(MUsuario usuario)
{
HttpClient _http = new HttpClient();
_http.BaseAddress = new Uri("http://localhost:60467/");
var request = _http.PostAsJsonAsync("api/Values",usuario).Result;
if (request.IsSuccessStatusCode)
{
return RedirectToAction("Index","Account");
}
else
{
return RedirectToAction("Registro", "Account");
}
}
Related
I have this form:
<form method="post" asp-controller="Auth" asp-action="RegisterUser">
<div class="form-group ms-1 my-1">
<input class="form-control" type="text" placeholder="Register Username" name="RegisterUsername" id="RegisterUsername"/>
</div>
<div class="form-group ms-1 my-3">
<input class="form-control" placeholder="Enter password" name="RegisterPassword" type="password" id="RegisterPassword"/>
</div>
<div class="form-group ms-1 my-3">
<input class="form-control" placeholder="Confirm password" name="registerConfirmPassword" type="password" id="RegisterConfirmPassword"/>
</div>
<div class="modal-footer">
<button type="submit" value="Submit" class="btn btn-success button button4">Register</button>
</div>
</form>
And this is found in my AuthController.cs file:
[HttpPost]
public IActionResult RegisterUser(string registerUsername, string registerPassword, string registerConfirmPassword)
{
Console.WriteLine("AAAAAAAAAAAAAAAAAAAA");
Console.WriteLine($"{registerUsername} - {registerPassword} - {registerConfirmPassword}");
return Ok();
}
Whenever I press the submit button nothing happens, please help me.
The form is in _Layout.cshtml and the post method is in another controller.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have an user profile page which user can update it own informations.
When I'm trying to update, im getting instance of entity type cannot be tracked because another instance with same key value is tracked error and i allready look around to solve this problem. I know i need to point that object as Detached so i can update it without taking any error in Try-Catch block. Let me show to you my frontend and my backend first.
Frontend :
<form class="mt-0" asp-action="MyProfile" enctype="multipart/form-data" method="post">
<input asp-for="User.UserID" type="hidden" value="#Model.User.UserID" name="UserID">
<input asp-for="User.UserPassword" type="hidden" value="#Model.User.UserPassword" name="UserPassword">
<input asp-for="User.UserEMail" type="hidden" value="#Model.User.UserEMail" name="UserEMail">
<input asp-for="User.UserToken" type="hidden" value="#Model.User.UserToken" name="UserToken">
<input asp-for="User.UserRequestToken" type="hidden" value="#Model.User.UserRequestToken" name="UserRequestToken">
<input asp-for="User.UserIsActive" type="hidden" value="#Model.User.UserIsActive" name="UserIsActive">
<input asp-for="User.UserIsEmailConfirmed" type="hidden" value="#Model.User.UserIsEmailConfirmed" name="UserIsEmailConfirmed">
<input asp-for="User.CompanyID" type="hidden" value="#Model.User.CompanyID" name="CompanyID">
<input asp-for="User.UserRoleID" type="hidden" value="#Model.User.UserRoleID" name="UserRoleID">
<input asp-for="User.CompanyIsAdmin" type="hidden" value="#Model.User.CompanyIsAdmin" name="CompanyIsAdmin">
<input asp-for="User.CreatedDate" type="hidden" value="#Model.User.CreatedDate" name="CreatedDate">
<div class="form-row mb-4">
<div class="col">
<label asp-for="User.UserName"><b>Kullanıcı Adı</b></label>
<input asp-for="User.UserName" type="text" class="form-control"
placeholder="Ad" name="UserName" value="#Model.User.UserName" required>
<span asp-validation-for="User.UserName" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="User.UserSurname"><b>Kullanıcı Soyadı</b></label>
<input asp-for="User.UserSurname" type="text" class="form-control"
placeholder="Soyad" name="UserSurname" value="#Model.User.UserSurname" required>
<span asp-validation-for="User.UserSurname" class="text-danger"></span>
</div>
</div>
<div class="form-row mb-4">
<div class="col">
<label asp-for="User.UserPhone"><b>Kullanıcı Telefonu</b></label>
<input asp-for="User.UserPhone" type="text" class="form-control"
placeholder="+905555555555" minlength="11" name="UserPhone" value="#Model.User.UserPhone" required>
<span asp-validation-for="User.UserPhone" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="User.UserBPhone"><b>Kullanıcı İş Telefonu</b></label>
<input asp-for="User.UserBPhone" type="text" class="form-control"
placeholder="+905555555555" minlength="11" name="UserBPhone" value="#Model.User.UserBPhone">
<span asp-validation-for="User.UserBPhone" class="text-danger"></span>
</div>
</div>
<button type="submit" name="MyProfile" class="btn btn-primary mt-2 mb-2 btn-block">
Update Your Informations
</button>
</form>
Backend :
#region /*UpdateMyProfile*/
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> MyProfile(User user)
{
try
{
if (ModelState.IsValid)
{
// That's the point where i got the null exception error
_context.Entry(user).State =Microsoft.EntityFrameworkCore.EntityState.Detached;
// That's the point where i got the null exception error
user.ModifiedDate = DateTime.Now;
user.ModifiedUserId = getCurrentUser();
user.ModifiedUserType = getCurrentUserClaimRole();
await _unitOfWorkUser.RepositoryUser.UpdateAsync(user);
await _unitOfWorkUser.CompleteAsync();
var log = _logging.Logging("Firma (Kullanıcı Bilgilerini) Güncelledi", "Update/Post",//
user.UserID.ToString(), "Company-MyProfile/UpdateMyProfile", getCurrentUser(), getCurrentUserClaimRole());
await _unitOfWorkLog.RepositoryLog.CreateAsync(log);
await _unitOfWorkLog.CompleteAsync();
return RedirectToAction("MyProfile");
}
else
{
TempData["Message"] = "İşleminiz Başarısız.";
TempData["JS"] = "showError();";
return RedirectToAction("MyProfile");
}
}
catch (Exception ex)
{
var log = _logging.Logging(ex.Message, "Exception/Hata", user.UserID.ToString(),
"MyProfile/UpdateMyProfile", getCurrentUser(), getCurrentUserClaimRole());
_unitOfWorkLog.RepositoryLog.Create(log);
_unitOfWorkLog.Complete();
TempData["Message"] = ex.Message;
TempData["JS"] = "showError();";
return RedirectToAction("MyProfile");
}
}
I point the Exception on the backend method. I Dont know why but im getting Null Exception when im trying to Detached the object. I dont know why im getting that error i mean its no making sense.
I always thought that using an UoW and a generic repository is never a good idea (read this for example https://gunnarpeipman.com/ef-core-repository-unit-of-work/ ) So this is code I would be using. You can modify it to UoW if you can or need
var userExisted=_context.Set<User>().FirstOrDefault(Id==user.Id);
if (userExisted==null) ....exception error
_context.Entry(userExisted).CurrentValues.SetValues(user);
userExisted.ModifiedDate = DateTime.Now;
userExisted.ModifiedUserId = getCurrentUser();
userExisted.ModifiedUserType = getCurrentUserClaimRole();
var result = await _context.SaveChangesAsync();
if(result==0) ...error
Update your Back-End code like this:-
//clarify code
if (!user.IsNull())
{
_context.Entry(user).State =Microsoft.EntityFrameworkCore.EntityState.Detached;
}
//clarify code
UPDATE
First of all,you have to create a ViewModel for your User model.
Assume that your ViewModel name is UserVM.
Now update your code like below:-
try
{
if (ModelState.IsValid)
{
UserVm user1= new UserVm()
{
UserName = user.UserName,
UserPhone= user.UserPhone,
//and so on as needed.
};
if (!user1.IsNull())
{
_context.Entry(user1).State =Microsoft.EntityFrameworkCore.EntityState.Detached;
}
//clarify code
try that,it should works.
My view model:
public class FileInfo
{
[Required]
[StringLength(50, ErrorMessage = "TitleErrorMessage", MinimumLength = 2)]
public string Title { get; set; }
[Required]
[StringLength(100, ErrorMessage = "DesErrorMessage", MinimumLength = 3)]
public string Description { get; set; }
[Required]
[DataType(DataType.Upload)]
public IFormFile File { get; set; }
}
The following is _UploadForm partial view file:
#model SessionStateTest.Models.FileInfo
<div class="form-group">
<label>Title</label>
<input class="form-control" asp-for="Title" />
</div>
<div class="form-group">
<label>Description</label>
<input class="form-control" asp-for="Description" />
</div>
<div class="form-group">
<label></label>
<input type="file" asp-for="File" />
</div>
That is used in another View with this code:
<form asp-action="AddUploadForm" asp-controller="Home" method="Post">
<input type="submit" value="Add another file" class="btn btn-sm btn-primary" />
</form>
<form asp-action="Upload" asp-controller="Home" method="Post" enctype="multipart/form-data">
#foreach (var item in Model.Upload)
{
#(await Html.PartialAsync("_UploadForm", item))
}
<div class="col-xs-12">
<input type="submit" value="Upload" class="btn btn-sm btn-info" />
</div>
</form>
Basically AddUploadForm action adds a new view model of type FileInfo to Model.Upload which is my main view model.
The problem is that the list List<FileInfo> vm in Upload action below is totally empty:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Upload(List<FileInfo> vm)
{
.... some other logic
return View();
}
I don't want to use multiple attribute because I would like to force user to provide a title and description for every file.
Any help is kindly appreciated!
Your approach with using _UploadForm generates the following html (let's focus on input's only since this is the most important part)
<input class="form-control" name="Title" />
<input class="form-control" name="Description" />
<input type="file" name="File" />
...
<input class="form-control" name="Title" />
<input class="form-control" name="Description" />
<input type="file" name="File" />
... and so on
So name attributes contains only FileInfo model's properties names without indexes and this is only suitable for the case when your controller expects single model
public IActionResult Upload(FileInfo vm)
And in order to make your html work with your current controller with list of models
public IActionResult Upload(List<FileInfo> vm)
It should look like this
<!-- version 1 -->
<input class="form-control" name="[0].Title" />
<input class="form-control" name="[0].Description" />
<input type="file" name="[0].File" />
...
<input class="form-control" name="[1].Title" />
<input class="form-control" name="[1].Description" />
<input type="file" name="[1].File" />
... and so on
Or
<!-- version 2 -->
<!-- the name before index must match parameter name in controller -->
<input class="form-control" name="vm[0].Title" />
<input class="form-control" name="vm[0].Description" />
<input type="file" name="vm[0].File" />
...
<input class="form-control" name="[1].Title" />
<input class="form-control" name="[1].Description" />
<input type="file" name="vm[1].File" />
... and so on
This is possible to accomplish using tag helpers and partial view in slightly different way. All you need to do is turn partial view's model to list and update asp-for expressions.
_UploadForm.cshtml
#model List<SessionStateTest.Models.FileInfo>
#for (int i = 0; i < Model.Count; i++)
{
<div class="form-group">
<label>Title</label>
<input class="form-control" asp-for="#Model[i].Title" />
</div>
<div class="form-group">
<label>Description</label>
<input class="form-control" asp-for="#Model[i].Description" />
</div>
<div class="form-group">
<label></label>
<input type="file" asp-for="#Model[i].File" />
</div>
}
View
<form asp-action="Upload" asp-controller="Home" method="Post" enctype="multipart/form-data">
#await Html.PartialAsync("_UploadForm", Model.Upload)
<div class="col-xs-12">
<input type="submit" value="Upload" class="btn btn-sm btn-info" />
</div>
</form>
It will generate html like in version 1.
I have changed a razor view to a handlebars template.
In the razor view:
using (Html.BeginForm("Start", "Form", FormMethod.Post, new { formTypeId = #Model.TypeId, organizationId = #Model.OrganizationId }))
{
#Html.AntiForgeryToken()
<input type="hidden" name="formTypeId" value="#Model.TypeId" />
<input type="hidden" name="organizationId" value="#Model.OrganizationId" />
<button class="btn btn-primary btn-block" type="submit">Start</button>
}
In the handlebars template:
<form action="{{StartLink}}" method="post">
<input type="hidden" name="formTypeId" value="{{TypeId}}" />
<input type="hidden" name="organizationId" value="{{OrganizationId}}" />
<button class="btn btn-primary btn-block" style="margin-bottom: 5px;" type="submit">Start</button>
</form>
I am unsure how to add the antiforgery token to the handlebars form.
ok here is what I came up with.
in my index.cshtml I pass an antiforgery token to the js that creates the handlebars template.
#section scripts {
<script>
$(function () {
window.formListBuilder = new app.components.FormListBuilder({
container: '#forms-container',
baseUrl: '#baseUrl.ToString()',
antiForgeryToken: '#Html.AntiForgeryToken()',
currentUser: JSON.parse('#Html.Raw(Json.Serialize(currentUser))')
})
});
</script>
}
then in the handlebars template I use the antiforgery token.
<form action="{{StartLink}}" method="post">
{{{antiForgeryToken}}}
<input type="hidden" name="formTypeId" value="{{TypeId}}" />
<input type="hidden" name="organizationId" value="{{OrganizationId}}" />
<button class="btn btn-primary btn-block" style="margin-bottom: 5px;" type="submit">Start</button>
</form>
is that an acceptable solution or does that bypass security in some way?
Update :
This is an SPA app.So it's having js file also for supporting the submit button.So I think problem is on it.Could you tell me how to modify it to support multiple kind of submit buttons ? At this moment I think it supports only for a single submit button.That is why it always get the first form's hidden field value I think.Thanks.
JS
var $loginForm = $('.login-form');
$loginForm.submit(function (e) {
e.preventDefault();
if (!$('.login-form').valid()) {
return;
}
abp.ui.setBusy(
null,
abp.ajax({
contentType: app.consts.contentTypes.formUrlencoded,
url: $loginForm.attr('action'),
data: $loginForm.serialize()
})
);
});
UI
VM
public class LoginViewModel
{
public string TenancyName { get; set; }
[Required]
public string UsernameOrEmailAddress { get; set; }
[Required]
public string Password { get; set; }
public bool RememberMe { get; set; }
}
CompanyLoginFormViewModel VM :
public class CompanyLoginFormViewModel
{
public LoginViewModel LoginViewModel { get; set; }
public List<TenantListDto> Tenants { get; set; }
}
*.cshtml page
#{
var companyLoginFormViewModel = TempData["CompanyLoginFormViewModel"] as CompanyLoginFormViewModel;
}
#foreach (var tenant in companyLoginFormViewModel.Tenants)
{
<form class="login-form" action="#Url.Action("Login")?returnUrl=#ViewBag.ReturnUrl" name="companyLoginForm" method="post">
<input type="hidden" name="usernameOrEmailAddress" value="#companyLoginFormViewModel.LoginViewModel.UsernameOrEmailAddress" />
<input type="hidden" name="password" value="#companyLoginFormViewModel.LoginViewModel.Password" />
<input type="hidden" name="rememberMe" value="true" />
<input type="hidden" name="companyUrl" value="true" />
<input type="hidden" name="tenancyName" value="#tenant.TenancyName" />
<div class="row margin-top-10">
<div class="col-xs-3">
<button type="submit" class="btn btn-success uppercase">#L("LogIn")</button>
</div>
</div>
</form>
}
Generated html
<form class="login-form" action="/Account/Login?returnUrl=/Application" name="companyLoginForm" method="post" novalidate="novalidate">
<input type="hidden" name="usernameOrEmailAddress" value="fake#gmail.com">
<input type="hidden" name="password" value="fake">
<input type="hidden" name="rememberMe" value="true">
<input type="hidden" name="companyUrl" value="true">
<input type="hidden" name="tenancyName" value="Asset_Management">
<div class="row margin-top-10">
<div class="col-xs-3">
<button type="submit" class="btn btn-success uppercase">Log in</button>
</div>
</div>
</form>
<form class="login-form" action="/Account/Login?returnUrl=/Application" name="companyLoginForm" method="post" novalidate="novalidate">
<input type="hidden" name="usernameOrEmailAddress" value="fake#gmail.com">
<input type="hidden" name="password" value="fake">
<input type="hidden" name="rememberMe" value="true">
<input type="hidden" name="companyUrl" value="true">
<input type="hidden" name="tenancyName" value="Associates">
<div class="row margin-top-10">
<div class="col-xs-3">
<button type="submit" class="btn btn-success uppercase">Log in</button>
</div>
</div>
</form>
<form class="login-form" action="/Account/Login?returnUrl=/Application" name="companyLoginForm" method="post" novalidate="novalidate">
<input type="hidden" name="usernameOrEmailAddress" value="fake#gmail.com">
<input type="hidden" name="password" value="fake">
<input type="hidden" name="rememberMe" value="true">
<input type="hidden" name="companyUrl" value="true">
<input type="hidden" name="tenancyName" value="ALL">
<div class="row margin-top-10">
<div class="col-xs-3">
<button type="submit" class="btn btn-success uppercase">Log in</button>
</div>
</div>
</form>
Post method
[HttpPost]
public virtual async Task<JsonResult> Login(LoginViewModel loginModel, string returnUrl = "", string returnUrlHash = "", bool companyUrl = false)
{
CheckModelState();
// removed for clarity
}
Question : Even though I have press the 2nd submit button,it always send the tenancyName as first submit button's value.That is Asset_Management.Could you tell me why ? Thanks.
Your problem is with the script.
var $loginForm = $('.login-form');
is a collection of all your forms, but
data: $loginForm.serialize(),
will only serialize the first one, so you always posting the vales of the first form. Modify the script to handle the buttons .click() event and get its associated form
$('.btn-success').click(function(e) {
e.preventDefault(); // if you makes the button type="button" this is not required
var form = $(this).closest('.login-form');
if (!form.valid()) {
return;
}
abp.ui.setBusy(
null,
abp.ajax({
contentType: app.consts.contentTypes.formUrlencoded,
url: form.attr('action'),
data: form.serialize()
})
);
});
Why do you even have <form> and <button> at all?
Why not create links in your foreach loop, something like this:
#Html.ActionLink("Login for " + tenant.Name, "LoginAction", new {Id=tenant.Id})
You can style these links all blue and pretty as you like using CSS afterwards.
Update1, you can pass parameters to your controller using the anonymous object. Do you see how I am passing Id? Your Action will need to accept id, see this answer: passing multiple parameters in #html.actionlink()
Update2, passing username and password like this is very bad practice. You are exposing secure credentials to the view. You should forward the user to the login page with username + password input boxes where the user will login.