|
Hi everyone
We host CodeProject on dedicated servers in a very grown up (read: expensive) hosting centre that has all the bells and whistles. This is great, but for a friend who's asking about cheap ASP.NET hosting I'm kind of at a loss as to what to recommend.
What are your thought?
Requirements:
- Must be able to host ASP.NET Core / .NET 5
- Must include SQL Server, MySQL or postgres (at least 10Gb)
- Doesn't need much CPU
- Doesn't need much disk storage
- Needs fast internet
- Must be affordable ($10 a month or less)
I've (personally) used Winhost but I can't recommend then. They are easy to use, have everything in the above list except speed. Their bandwidth is pretty awful.
What are your thoughts?
cheers
Chris Maunder
|
|
|
|
|
I'll toss something into the basket here Chris.
Most developers went cloud or Azure, AWS Amazon and Google.
They even went cloud with CDN to call CSS, Fonts, etc.
I looked into pricing once, you can check off boxes for SQL server, MySQL, Cosmos, Mongo
Choose how much bandwidth you want, bandwidth on demand.
But it seems to really boil down to how you package your project and how little it's used. The average seems to be 7 to 13 cents a hour which is about $50.40 to $93.60 a month max. I'm not sure if the price represents active use of the container or app, and you don't pay when the container or app is idle.
Container pricing - where your container just floats in the system and gets served.
Pricing - Container Instances | Microsoft Azure
Traditional pricing including virtual machines
App Service Pricing | Microsoft Azure
But considering the price of electricity, service techs, support, cost of software licensing, and profit there is no way in 2021 can you do this for $10 a month in western democracies using that technology unless you have a friend that gives you a solid. I would try looking in places with cheap electricity and fast internet connections like Moldova, Romania, Ukraine, Southern Texas, Central China, Bulgaria, Montenegro, Croatia. I'm not kidding.
On the other hand, you can host a Wordpress, Joomla, PHP app for dirt cheap, as low as $1 a month I've seen anywhere in the world. It's the price of the technology, application packaging, electricity that plays a huge factor in price.
Haven't talk to you in a long time. I made lots of money in the last 18 months off being a rogue programmer and changing my business model and advertising. Finally bought a car after 18 years of doing this, picked up a really clean used CPO 2018 Porsche Macan GTS with all the power train toys and low miles. There's good money to be made in PHP, but not much help with it.
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
Nice work on the car! That's awesome.
Your comment about actual hours vs "month" hours is very valid, and for this app it will be run very rarely (to start with).
To put this in perspective I am currently using WinHost for about $8/month and it comes with Windows, .NET 5 support and SQL Server. It's everything I need. Except the ability to scale and it has terrible bandwidth.
There is a place in Germany that offers dedicated servers for about $30 a month (if I remember correctly). You get the bare metal and off you go. They have awesome bandwidth and service. But they are in Germany and with the world being the world, jurisdictions come into play and make life difficult.
It's crazy this is still a difficult decision to analyse
cheers
Chris Maunder
|
|
|
|
|
Yeh Chris,
But bare metal is not scalable nor very redundant. With these these new cloud services you can turn the knob up and down on bandwidth, how many CPU's, or how many nodes process your application. So If this is seasonal say a Xmas application that sells sausage and cheese, you can turn the dial to max on Black Friday and turn it back down in January. I think you can also filter out bots by country as well to reduce bandwidth. Or if you keep all the dials real low, you can slow everything down to keep your bill down at the same level. Compared to $30 a month for bare metal, I'd choose the latter.
Then you get into packaging your app at that .Net Core level, where you can put it in a container and just upload the whole container and off it goes. If it gets hacked you just replace the container with another copy. With Docker you can make a Linux container that serves up your .Net app and even include SQL Server for Linux, and anything else you need to run your app in a single container. This reduces your software licensing cost by going Linux versus choosing a Windows Server container. And Docker now supports the new container format as well, so it doesn't have to be a Docker container anymore. You can now even package or create a Kubernetes container that can spawn across a Kubernetes cluster that is scalable as well. You just set how many times max that you wish to scale out the app when busy and how many to idle back down to.
How you plan and package your app will have a huge effect on your hosting options and how much you end up paying for it. If you look at my website, it runs in a Linux Docker container using .Net Core support for Linux, with Linux MongoDB infused inside the container as well. This container has a builtin network to support protected communications between the app and MongoDB, and gets served up using Kestrel 2.0 (Http2 with builtin Certificate) that is infused as well. The container listens on a odd number port that is not port 80 or 443 to further secure the container. Finally, this container runs on a Dell Linux cluster of 3 servers that is configured for Kubernetes nodes on super fast SSD drives running Ubuntu Linux command line only. I didn't have the heart to toss out my hardware so I rebuilt it as a cloud service model to experiment with before I pay those high prices. Because of my final litigation with the BSA and Microsoft, we agreed upon me going open source from this point on.
I've been studying this technology for 4 years now, but have been rogue implementing it. After participating in 100's of programmer meetups, this is the consensus now of how to do it in Irvine CA. But very few people can actually do this scope of work.
Kind of strange that I'm sharing this with you, but I'm not sure what the scope of your friends project is, so it may have very simple requirements that your trying to keep at a very simple level yet use the latest versions of .Net 5 which is super cool. I know what you mean by Jurisdictions but sometimes you have to cross them or remain outside of them.
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
Chris,
Did you try looking at this DiscountASP.NET hosting plan details[^] ?
Not sure how about their current performance but once upon a time we had a few demos and prototypes hosted through them. At a $10 budget they seem to be having a few things to offer too.
|
|
|
|
|
Interestingly while debugging an issue with WinHost I found that they use DiscountASP.NETs servers, so either white labelling DiscountASP.NET or simply a rebranded business unit under DiscountASP.NET directly.
So I'd have to say a big no to them, unfortunately. Cheap, easy to use, great for demos and small things, absolutely. But painfully slow
cheers
Chris Maunder
|
|
|
|
|
smarterasp.net
Tried switching a few times but got greatly discouraged and reverted due to the complexity of the software used to perform hosting related tasks. Plesk I think it was called. All 3 alternatives used it.
Their support is pretty decent too.
|
|
|
|
|
dear team can you help me on this
|
|
|
|
|
good day, am in the process of deploying an application on azure. the app was build on ASP.NET CORE with ANGULAR 2. But when i finished the deployment process it shows that all succeeded -and when it load the URL just saying "Loading..." nothing comes up, then when inspect the page i get the following error "ailed to load resource: the server responded with a status of 404 (Not Found)" and error "Uncaught Reference Error: System is not defined at (index):18" can some one assist me what steps i can follow to resolve this matter? URL:https://[DELETED].net/ Thanks
modified 9-Jul-21 13:52pm.
|
|
|
|
|
Either something did not deploy all the way or your urls are not done properly such that when published they are not correct anymore.
You'll have to use your developer tools to figure out what is going on or what is missing.
|
|
|
|
|
|
|
Hi,
I would like to Upgrade the Publish page into latest version(Publish Web) in Visual Studio 2012. I still have the older page to publish my Application. How do i upgrade this. Please let me know.
modified 4-Jul-21 7:05am.
|
|
|
|
|
The version of the "publish" page is linked to the version of Visual Studio. If you want the newer page, you need to upgrade Visual Studio.
VS2019 community edition is free, so there's no reason to continue using such an ancient version:
Visual Studio Community 2019 - Free IDE and Developer Tools[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Hi All I am new to MVC and EntityFramework and am having a problem getting my form to save changes back to the database.
I have the following model
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Services.Providers;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HAZID.Core.Models
{
public class HAZID_Forms : HAZID_Base_Entity
{
[Display(Name = "HAZID_Workers_Id", ResourceType = typeof(Resources.Resource))]
[Required(ErrorMessageResourceName = "HAZID_Workers_Id_Error_Msg", ErrorMessageResourceType = typeof(Resources.Resource))]
public int HAZID_Workers_Id { get; set; }
[Display(Name = "HAZID_Supervisors_Id", ResourceType = typeof(Resources.Resource))]
[Required(ErrorMessageResourceName = "HAZID_Supervisor_Id_Error_Msg", ErrorMessageResourceType = typeof(Resources.Resource))]
public int HAZID_Supervisors_Id { get; set; }
[Display(Name = "HAZID_Form_DateTime", ResourceType = typeof(Resources.Resource))]
public DateTime HAZID_Form_DateTime { get; set; }
[Display(Name = "HAZID_District_Id", ResourceType = typeof(Resources.Resource))]
[Required(ErrorMessageResourceName = "HAZID_District_Id_Error_Msg", ErrorMessageResourceType = typeof(Resources.Resource))]
public int HAZID_District_Id { get; set; }
[Display(Name = "HAZID_Hazard_Location", ResourceType = typeof(Resources.Resource))]
[DataType(DataType.MultilineText)]
[Required(ErrorMessageResourceName = "HAZID_Hazard_Location_Error_Msg", ErrorMessageResourceType = typeof(Resources.Resource))]
public string HAZID_Hazard_Location { get; set; }
[Display(Name = "HAZID_Hazard_Description", ResourceType = typeof(Resources.Resource))]
[DataType(DataType.MultilineText)]
[Required(ErrorMessageResourceName = "HAZID_Hazard_Description_Error_Msg", ErrorMessageResourceType = typeof(Resources.Resource))]
public string HAZID_Hazard_Description { get; set; }
public string HAZID_Hazard_Description_Short { get { return HAZID_Hazard_Description.ToString().SubStringTo(30); } }
[Display(Name = "HAZID_Workers_Suggstion", ResourceType = typeof(Resources.Resource))]
[DataType(DataType.MultilineText)]
public string HAZID_Workers_Suggstion { get; set; }
public string HAZID_Workers_Suggstion_Short { get { return HAZID_Workers_Suggstion.ToString().SubStringTo(30); } }
[Display(Name = "HAZID_Position", ResourceType = typeof(Resources.Resource))]
public string HAZID_Position { get; set; }
[Display(Name = "HAZID_Status_Id", ResourceType = typeof(Resources.Resource))]
public int? HAZID_Status_Id { get; set; }
[Display(Name = "HAZID_Hazard_Type_Id", ResourceType = typeof(Resources.Resource))]
public int? HAZID_Hazard_Type_Id { get; set; }
[Display(Name = "HAZID_Control_Description", ResourceType = typeof(Resources.Resource))]
[DataType(DataType.MultilineText)]
public string HAZID_Control_Description { get; set; }
[Display(Name = "HAZID_Person_Responsible_Name", ResourceType = typeof(Resources.Resource))]
public string HAZID_Person_Responsible_Name { get; set; }
[Display(Name = "HAZID_Applcability_To_Others_Flag", ResourceType = typeof(Resources.Resource))]
public bool HAZID_Applcability_To_Others_Flag { get; set; }
[Display(Name = "HAZID_Risk_Severity_Id", ResourceType = typeof(Resources.Resource))]
public int? HAZID_Risk_Severity_Id { get; set; }
[Display(Name = "HAZID_Risk_Probability_Id", ResourceType = typeof(Resources.Resource))]
public int? HAZID_Risk_Probability_Id { get; set; }
[Display(Name = "HAZID_Action_Taken", ResourceType = typeof(Resources.Resource))]
[DataType(DataType.MultilineText)]
public string HAZID_Action_Taken { get; set; }
}
}
Two ViewModels
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HAZID.Core.Models;
namespace HAZID.Core.ViewModels
{
public class HAZID_Form_View_Model
{
public HAZID_Forms HAZID_Form { get; set; }
public IEnumerable<HAZID_Branch_Districts> HAZID_Branch_Districts { get; set; }
public IEnumerable<HAZID_Persons> HAZID_Persons { get; set; }
public IEnumerable<HAZID_Hazard_Types> HAZID_Hazard_Types { get; set; }
public IEnumerable<HAZID_Risk_Severity_Types> HAZID_Risk_Severity_Types { get; set; }
public IEnumerable<HAZID_Risk_Probability_Types> HAZID_Risk_Probability_Types { get; set; }
public IEnumerable<HAZID_Statuses> HAZID_Statuses { get; set; }
}
}
<pre>using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HAZID.Core.Models;
namespace HAZID.Core.ViewModels
{
public class HAZID_Forms_View_Model
{
public IEnumerable<HAZID_Forms> HAZID_Forms { get; set; }
public IEnumerable<HAZID_Branch_Districts> HAZID_Branch_Districts { get; set; }
public IEnumerable<HAZID_Hazard_Types> HAZID_Hazard_Types { get; set; }
public IEnumerable<HAZID_Risk_Severity_Types> HAZID_Risk_Severity_Types { get; set; }
public IEnumerable<HAZID_Risk_Probability_Types> HAZID_Risk_Probability_Types { get; set; }
public IEnumerable<HAZID_Statuses> HAZID_Statuses { get; set; }
public IEnumerable<HAZID_Persons> HAZID_Persons { get; set; }
}
}
The Controller looks like this
using HAZID.Core.Contracts;
using HAZID.Core.Models;
using HAZID.Core.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace HAZID.WebUI.Controllers
{
public class HAZID_ApplicationController : Controller
{
IHAZID_Repository<HAZID_Forms> hazidForms;
IHAZID_Repository<HAZID_Branch_Districts> hazidBranchDistricts;
IHAZID_Repository<HAZID_Hazard_Types> hazidHazardTypes;
IHAZID_Repository<HAZID_Risk_Severity_Types> hazidRiskSeverityTypes;
IHAZID_Repository<HAZID_Risk_Probability_Types> hazidRiskProbabilityTypes;
IHAZID_Repository<HAZID_Statuses> hazidStatuses;
IHAZID_Repository<HAZID_Persons> hazidPersons;
public HAZID_ApplicationController(IHAZID_Repository<HAZID_Forms> hazidFormContext, IHAZID_Repository<HAZID_Branch_Districts> hazidBranchDistrictContext,
IHAZID_Repository<HAZID_Hazard_Types> hazidHazardTypeContext, IHAZID_Repository<HAZID_Risk_Severity_Types> hazidRiskSeverityTypeContext,
IHAZID_Repository<HAZID_Risk_Probability_Types> hazidRiskProbabilityTypeContext, IHAZID_Repository<HAZID_Statuses> hazidStatusContext,
IHAZID_Repository<HAZID_Persons> hazidPersonContext)
{
this.hazidForms = hazidFormContext;
this.hazidBranchDistricts = hazidBranchDistrictContext;
this.hazidHazardTypes = hazidHazardTypeContext;
this.hazidRiskSeverityTypes = hazidRiskSeverityTypeContext;
this.hazidRiskProbabilityTypes = hazidRiskProbabilityTypeContext;
this.hazidStatuses = hazidStatusContext;
this.hazidPersons = hazidPersonContext;
}
public ActionResult ListReports()
{
HAZID_Forms_View_Model hazidFormsViewModel = new HAZID_Forms_View_Model();
hazidFormsViewModel.HAZID_Forms = hazidForms.Collection().ToList();
hazidFormsViewModel.HAZID_Branch_Districts = hazidBranchDistricts.Collection();
hazidFormsViewModel.HAZID_Hazard_Types = hazidHazardTypes.Collection();
hazidFormsViewModel.HAZID_Risk_Severity_Types = hazidRiskSeverityTypes.Collection();
hazidFormsViewModel.HAZID_Risk_Probability_Types = hazidRiskProbabilityTypes.Collection();
hazidFormsViewModel.HAZID_Statuses = hazidStatuses.Collection();
hazidFormsViewModel.HAZID_Persons = hazidPersons.Collection();
return View(hazidFormsViewModel);
}
public ActionResult EditReport(int id)
{
HAZID_Forms hazidFormToEdit = hazidForms.Find(id);
if (hazidFormToEdit == null)
{
return HttpNotFound();
}
else
{
HAZID_Form_View_Model hazidFormViewModel = new HAZID_Form_View_Model();
hazidFormViewModel.HAZID_Form = hazidFormToEdit;
hazidFormViewModel.HAZID_Branch_Districts = hazidBranchDistricts.Collection();
hazidFormViewModel.HAZID_Hazard_Types = hazidHazardTypes.Collection();
hazidFormViewModel.HAZID_Risk_Severity_Types = hazidRiskSeverityTypes.Collection();
hazidFormViewModel.HAZID_Risk_Probability_Types = hazidRiskProbabilityTypes.Collection();
hazidFormViewModel.HAZID_Statuses = hazidStatuses.Collection();
hazidFormViewModel.HAZID_Persons = hazidPersons.Collection();
return View(hazidFormViewModel);
}
}
[HttpPost]
public ActionResult EditReport(HAZID_Form_View_Model hazidFormViewModel, int id)
{
HAZID_Forms hazidFormToEdit = hazidForms.Find(id);
if (hazidFormToEdit == null)
{
return HttpNotFound();
}
else
{
if (!ModelState.IsValid)
{
return View(hazidFormViewModel);
}
hazidFormToEdit = hazidFormViewModel.HAZID_Form;
hazidForms.Commit();
return RedirectToAction("ListReports");
}
}
public ActionResult ViewForm(int id)
{
HAZID_Forms hazidFormToView = hazidForms.Find(id);
if (hazidFormToView == null)
{
return HttpNotFound();
}
else
{
HAZID_Form_View_Model hazidFormViewModel = new HAZID_Form_View_Model();
hazidFormViewModel.HAZID_Form = hazidFormToView;
hazidFormViewModel.HAZID_Branch_Districts = hazidBranchDistricts.Collection();
hazidFormViewModel.HAZID_Hazard_Types = hazidHazardTypes.Collection();
hazidFormViewModel.HAZID_Risk_Severity_Types = hazidRiskSeverityTypes.Collection();
hazidFormViewModel.HAZID_Risk_Probability_Types = hazidRiskProbabilityTypes.Collection();
hazidFormViewModel.HAZID_Statuses = hazidStatuses.Collection();
hazidFormViewModel.HAZID_Persons = hazidPersons.Collection();
return View(hazidFormViewModel);
}
}
}
}
My Edit view looks like this
@model HAZID.Core.ViewModels.HAZID_Form_View_Model
@{
ViewBag.Title = "Edit Report";
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>HASS Report Details</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.HAZID_Form.Id)
@Html.HiddenFor(model => model.HAZID_Form.HAZID_Workers_Id)
@Html.HiddenFor(model => model.HAZID_Form.HAZID_Form_DateTime)
@Html.HiddenFor(model => model.HAZID_Form.HAZID_District_Id)
@Html.HiddenFor(model => model.HAZID_Form.HAZID_Supervisors_Id)
@Html.HiddenFor(model => model.HAZID_Form.HAZID_Hazard_Location)
@Html.HiddenFor(model => model.HAZID_Form.HAZID_Hazard_Description)
@Html.HiddenFor(model => model.HAZID_Form.HAZID_Workers_Suggstion)
<div class="form-group col-md-10">
<div class="row">
<div class="col-3">
@Html.CustomLabelFor(model => model.HAZID_Form.HAZID_Workers_Id)
</div>
<div class="col-7">
@Html.Raw(Model.HAZID_Persons.FirstOrDefault(c => c.Id == Model.HAZID_Form.HAZID_Workers_Id).Full_Name)
</div>
</div>
<div class="row">
<div class="col-3">
@Html.CustomLabelFor(model => model.HAZID_Form.HAZID_Position)
</div>
<div class="col-7">
@Html.Raw(Model.HAZID_Form.HAZID_Position)
</div>
</div>
<div class="row">
<div class="col-3">
@Html.CustomLabelFor(model => model.HAZID_Form.HAZID_Form_DateTime)
</div>
<div class="col-7">
@Html.Raw(Model.HAZID_Form.HAZID_Form_DateTime.ToString())
</div>
</div>
<div class="row">
<div class="col-3">
@Html.CustomLabelFor(model => model.HAZID_Form.HAZID_Supervisors_Id)
</div>
<div class="col-7">
@Html.Raw(Model.HAZID_Persons.FirstOrDefault(c => c.Id == Model.HAZID_Form.HAZID_Supervisors_Id).Full_Name)
</div>
</div>
<div class="row">
@{
var hazidDistrictName = string.Empty;
if (System.Threading.Thread.CurrentThread.CurrentUICulture.Name == "en")
{
hazidDistrictName = Model.HAZID_Branch_Districts.FirstOrDefault(c => c.Id == Model.HAZID_Form.HAZID_District_Id).English_Description.ToString();
}
else
{
hazidDistrictName = Model.HAZID_Branch_Districts.FirstOrDefault(c => c.Id == Model.HAZID_Form.HAZID_District_Id).French_Description.ToString();
}
}
<div class="col-3">
@Html.CustomLabelFor(model => model.HAZID_Form.HAZID_District_Id)
</div>
<div class="col-7">
@Html.Raw(hazidDistrictName)
</div>
</div>
<div class="row">
<div class="col-3">
@Html.CustomLabelFor(model => model.HAZID_Form.HAZID_Hazard_Location)
</div>
<div class="col-7">
@Html.Raw(Model.HAZID_Form.HAZID_Hazard_Location)
</div>
</div>
<div class="row">
<div class="col-3">
@Html.CustomLabelFor(model => model.HAZID_Form.HAZID_Hazard_Description)
</div>
<div class="col-7">
@Html.Raw(Model.HAZID_Form.HAZID_Hazard_Description)
</div>
</div>
<div class="row">
<div class="col-3">
@Html.CustomLabelFor(model => model.HAZID_Form.HAZID_Workers_Suggstion)
</div>
<div class="col-7">
@Html.Raw(Model.HAZID_Form.HAZID_Workers_Suggstion)
</div>
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.HAZID_Form.HAZID_Status_Id, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-3">
@Html.DropDownListFor(model => model.HAZID_Form.HAZID_Status_Id, new SelectList(Model.HAZID_Statuses, "Id", Resources.Resource.HAZID_Column_Select), Resources.Resource.HAZID_Status_Id_Select, new { htmlAttributes = new { @class = "form-control", id = "HAZID_Form_HAZID_Status_Id" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.HAZID_Form.HAZID_Action_Taken, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.HAZID_Form.HAZID_Action_Taken, new { htmlAttributes = new { @class = "form-control", @style = "width:100% !important; min-width:600px; height:100px" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.HAZID_Form.HAZID_Hazard_Type_Id, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-4">
@Html.DropDownListFor(model => model.HAZID_Form.HAZID_Hazard_Type_Id, new SelectList(Model.HAZID_Hazard_Types, "Id", Resources.Resource.HAZID_Column_Select), Resources.Resource.HAZID_Hazard_Type_Select, new { htmlAttributes = new { @class = "form-control", id = "HAZID_Form_HAZID_Hazard_Type_Id" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.HAZID_Form.HAZID_Risk_Severity_Id, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-4">
@Html.DropDownListFor(model => model.HAZID_Form.HAZID_Risk_Severity_Id, new SelectList(Model.HAZID_Risk_Severity_Types, "Id", Resources.Resource.HAZID_Column_Select), Resources.Resource.HAZID_Risk_Severity_Id_Select, new { htmlAttributes = new { @class = "form-control", id = "HAZID_Form_HAZID_Risk_Severity_Id" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.HAZID_Form.HAZID_Hazard_Type_Id, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-4">
@Html.DropDownListFor(model => model.HAZID_Form.HAZID_Risk_Probability_Id, new SelectList(Model.HAZID_Risk_Probability_Types, "Id", Resources.Resource.HAZID_Column_Select), Resources.Resource.HAZID_Risk_Probability_Id_Select, new { htmlAttributes = new { @class = "form-control", id = "HAZID_Form_HAZID_Risk_Probability_Id" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.HAZID_Form.HAZID_Control_Description, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-4">
@Html.EditorFor(model => model.HAZID_Form.HAZID_Control_Description, new { htmlAttributes = new { @class = "form-control", @style = "width:100% !important; min-width:600px; height:100px" } })
@Html.ValidationMessageFor(model => model.HAZID_Form.HAZID_Control_Description, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.HAZID_Form.HAZID_Person_Responsible_Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.HAZID_Form.HAZID_Person_Responsible_Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.HAZID_Form.HAZID_Person_Responsible_Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.HAZID_Form.HAZID_Applcability_To_Others_Flag, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.CheckBoxFor(model => model.HAZID_Form.HAZID_Applcability_To_Others_Flag)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-outline-primary" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "ListReports")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(function () {
$("#HAZID_Form_HAZID_Status_Id").select2();
$("#HAZID_Form_HAZID_Hazard_Type_Id").select2();
$("#HAZID_Form_HAZID_Risk_Severity_Id").select2();
$("#HAZID_Form_HAZID_Risk_Probability_Id").select2();
$('.select2-container').css("width", "100%");
});
</script>
}
My problem is when I click the save the data is there but after the commit and redirect the data was not saved to the database.
if someone can help me it would be very much appreciated.
|
|
|
|
|
Member 15016778 wrote:
HAZID_Forms hazidFormToEdit = hazidForms.Find(id);
...
hazidFormToEdit = hazidFormViewModel.HAZID_Form;
hazidForms.Commit(); Your code finds the form with the specified ID, and stores it in a local variable.
It then overwrites the local variable with the value from the view-model, breaking any link between the variable and the repository.
It then tells the repository to commit the changes. But there are no changes to commit, because you've not updated anything that the repository knows about.
Instead of overwriting the local variable, you need to update the entity returned from the Find method using the properties of the view-model.
You'll also need to repopulate the view-model collections before displaying the view again.
private void PopulateLookups(HAZID_Form_View_Model hazidFormViewModel)
{
hazidFormViewModel.HAZID_Branch_Districts = hazidBranchDistricts.Collection();
hazidFormViewModel.HAZID_Hazard_Types = hazidHazardTypes.Collection();
hazidFormViewModel.HAZID_Risk_Severity_Types = hazidRiskSeverityTypes.Collection();
hazidFormViewModel.HAZID_Risk_Probability_Types = hazidRiskProbabilityTypes.Collection();
hazidFormViewModel.HAZID_Statuses = hazidStatuses.Collection();
hazidFormViewModel.HAZID_Persons = hazidPersons.Collection();
}
[HttpGet]
public ActionResult EditReport(int id)
{
HAZID_Forms hazidFormToEdit = hazidForms.Find(id);
if (hazidFormToEdit == null)
{
return HttpNotFound();
}
HAZID_Form_View_Model hazidFormViewModel = new HAZID_Form_View_Model();
hazidFormViewModel.HAZID_Form = hazidFormToEdit;
PopulateLookups(hazidFormViewModel);
return View(hazidFormViewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditReport(HAZID_Form_View_Model hazidFormViewModel, int id)
{
HAZID_Forms hazidFormToEdit = hazidForms.Find(id);
if (hazidFormToEdit == null)
{
return HttpNotFound();
}
if (!ModelState.IsValid)
{
PopulateLookups(hazidFormViewModel);
return View(hazidFormViewModel);
}
hazidFormToEdit.HAZID_Status_Id = hazidFormViewModel.HAZID_Form.HAZID_Status_Id;
hazidFormToEdit.HAZID_Action_Taken = hazidFormViewModel.HAZID_Form.HAZID_Action_Taken;
...
hazidForms.Commit();
return RedirectToAction("ListReports");
}
NB: Don't use @Html.Raw(...) when displaying values in your view unless you expect the property to contain valid HTML which you want to include in your output. As it stands, your code is vulnerable to a persisted cross-site scripting (XSS) attack[^].
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thanks soo much that makes since. I just thought i could copy the whole thing in one step but now i see that is not the case.
As for the raw i was once again not sure as I need to get the text from a different column based on the language.
If you know a better way i would appreciate any insight.
|
|
|
|
|
Hi,
My solution have 3 layers (Business class project, Data Class Project and Application (ASP.Net, C#)). I can build Business and Data Class project, but when i build solution my Visual studio freezes and not showing any result in Output. after 5 or 10 minutes will get pop up message "Visual studio stopped working" and restart visual studio. I tried the below solutions to sort this issue, but nothing did help me.
1) Deleted files from Temporary folders
1.1)C:\Users\<user name="">\AppData\Local\Temp\Temporary ASP.NET Files
1.2)C:\Users\<user name="">\AppData\Local\Microsoft\WebsiteCache
1.3) C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files
1.4) C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files
2) Repair Visual studio
3) Uninstall and Re-Install Visual studio
4) Delete the .SUO file
I Can build this solution in my Personnel laptop(Windows 7) but in my workstation(Windows 8) have this problem. I am using Visual Studio 2012.
Please help me to sort this issue.
|
|
|
|
|
You need to report the problem to Microsoft.
But the obvious question is, why are you using a version of Visual Studio from nine years ago, when VS2019 community edition is available for free?
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Did you try the latest versions of Visual Studio like 2017 or 2019? They have radical improvements right from the installer stage.
|
|
|
|
|
How do you get dynamically loaded tabs to work in ASP.Net Core MVC?
1. I have a simple Index.cshtml that uses bootstrap tabs to create two tabs from the a tags on the page. (To test out options, I first copied from https://qawithexperts.com/article/asp.net/bootstrap-tabs-with-dynamic-content-loading-in-aspnet-mvc/176)
2. There is a click event on each tab that uses $.ajax() to call the controller and then set the html of the appropriate div.
3. I have a model with one field, a string that is required.
4. I have the create view that Visual Studio created.
5. When I run it and click the first tab, the controller returns PartialView("FirstTabCreate") and loads into the div and everything looks great.
6. The problem is when clicking the "Create" button.
7. The controller method checks if IsValid on the ModelState. If not, here is where I run into a problem. If I return the partial view and the model that was passed in I see my validation errors as expected but because I returned the partial view, I lose my tabs. If I return the main view (Index) then the javascript reloads my partial view and has lost the ModelState at that point.
I am not sure what to return so that this works. I have seen lots of examples online that use dynamically loaded tabs but none of them have models or validation.
Code below: Index Page
@model FirstTab
<!-- Tab Buttons -->
<ul id="tabstrip" class="nav nav-tabs" role="tablist">
<li class="active">
<a href="#FirstTab" role="tab" data-toggle="tab">Submission</a>
</li>
<li>
<a href="#SecondTab" role="tab" data-toggle="tab">Search</a>
</li>
</ul>
<!-- Tab Content Containers -->
<div class="tab-content">
<div class="tab-pane active" id="FirstTab">
</div>
<div class="tab-pane fade" id="SecondTab">
</div>
</div>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script>
$('#tabstrip a').click(function (e) {
e.preventDefault();
var tabID = $(this).attr("href").substr(1);
$(".tab-pane").each(function () {
console.log("clearing " + $(this).attr("id") + " tab");
$(this).empty();
});
$.ajax({
url: "/@ViewContext.RouteData.Values["controller"]/" + tabID,
cache: false,
type: "get",
dataType: "html",
success: function (result) {
$("#" + tabID).html(result);
}
});
$(this).tab('show');
});
$(document).ready(function () {
$('#tabstrip a')[0].click();
});
</script>
FirstTabCreate View
@model WebApplication1.Models.FirstTab
<h4>FirstTab</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="FirstTabCreate">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="FirstName" class="control-label"></label>
<input asp-for="FirstName" class="form-control" />
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
Model
using System.ComponentModel.DataAnnotations;
namespace WebApplication1.Models
{
public class FirstTab
{
[Required()]
public string FirstName { get; set; }
}
}
Controller
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public ActionResult FirstTab()
{
return PartialView("FirstTabCreate");
}
public ActionResult FirstTabCreate(FirstTab model)
{
if (!ModelState.IsValid)
{
return View("FirstTabCreate", model);
}
return Content("Success");
}
public ActionResult SecondTab()
{
return PartialView("_SecondTab");
}
}
}
|
|
|
|
|
|
Thanks, this does work but it does not solve my issue. Doing this essentially causes the form validation to happen all client side and so my Controller method does not get called. One of the business requirements is to log validation errors in the database, which I was doing in the Controller method when ModelState was not valid.
I'll look to see if there is a way to get all validation errors client side so that I can still log them in the db. It just seems like there should be an easier way to do tabs.
|
|
|
|
|
Client-side validation prevents a costly round-trip to the server, and reduces the number of times the server code has to run just to reject the request as invalid.
If you log every single validation error, then unless you're very lucky with your users, I suspect you're going to end up with a "validation errors" database that grows by hundreds of gigabytes every day.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Speed is an important part of this data entry app and so they want to know who keeps making the same mistakes over and over. For example, who keeps forgetting to fill in a phone number. This way they can train users to be more efficient.
So, I get your point, but no, it won't be nearly that bad.
We actually are replacing a Java based web app and the current table for validation errors is big, but not too big.
|
|
|
|
|