Model Validation using Data Annotations not working on Mac VS.NET - macos

I created a new Web API Application on MacOS with VS.NET. I added a model with the following code:
public class PersonAddRequest {
[Required]
public string FirstName { get; set; }
public string LastName { get; set; }
}
Then I created a Web API Controller like so:
[Route("api/[controller]")]
[ApiController]
public class PeopleController : ControllerBase {
[HttpPost]
public IActionResult Post(PersonAddRequest model) {
return base.Ok(model);
}
}
When using PostMan I post JSON as so (note firstName is missing):
{
"lastName":"McDonalds"
}
When I run this code on a Web API Application created on a Windows OS validation works as expected. However, when I create the project in MacOS validation doesn't work.
When I create the project in Windows OS then open and run it on MacOS, validation works!
So my question, is this a feature that is missing as part of the scaffolding on VS.NET for Mac?

You require the FromBody attribute for the body argument:
[Route("api/[controller]")]
[ApiController]
public class PeopleController : Controller
{
[HttpPost]
public IActionResult Post([FromBody]PersonAddRequest model)
{
return Ok(model);
}
}
This is required for model validation.
Here's an example git repo using this form of model validation that is confirmed working on MacOS Mojave 10.14.4

I want to thank #nelsontruran for helping me explore VS.NET on Mac. I'm actually running a later version of the Mac (10.14.5 Mojave). However, the version had nothing to do with the original problem.
Thru the patients and persistent help of #nelsontruran I recreated the project but instead of using the suggested templates I dug around a little for the correct application (don't trust the suggested applications in VS.NET). Here's the step-by-step instructions on how to create an API that automatically performs model validation:
Open VS.NET for Mac
Create a new project
When prompted to "Choose a template for your new project", select "App" under the ".Net Core" section on the left side pane.
On the right side pane, select API
From there you can review #nelsontruran's example on git to see the magic of Model Validation.
I believe I might have been choosing "Web Application" thinking that it would be the same in Mac as it is in Windows.
A simple oversight on my part. I hope this helps someone who was confused and struggling like me.
Thank you again to #nelsontruran!!!

Related

Error trying to scaffold a view in ASP.NET Core 6.0 MVC

I'm trying to scaffold a new razor view using Visual Studio. I select a template, my model and my DbContext, then I get the error message shown below.
Things to note. My models, my DbContext and my website are all in different projects. From the message below I am using AddDbContext and I have a constructor that accepts a DbContextOptions<TContext> parameter.
I read a comment on a blog post that the issue is because my context is in another project. The comment referenced something about the need to inject the Configuration into the DbContext to get the connection string and manually add it in the OnConfiguring override.
I can't find any examples if this is correct or how to set it up. Any help would be appreciated.
EDIT:
Testing out the theory from the blog comment I mentioned above, I added this section into my DbContext. ConnectionString is a hardcoded string constant with my connection information. This does work and allow me to scaffold, so the question still remains. How can I inject this connection string into my DbContext to allow the scaffolding to work?
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(ConnectionString);
}
else
{
base.OnConfiguring(optionsBuilder);
}
}
EDIT: So after making this change, I checked in the code and had another developer pick it up. It appears this section above just needs to be there to allow scaffolding to work. He never changed the connection string to point to his environment. He no longer got the error above it just worked.
I am not sure about what is the actual problem but it seems like we were having problems creating DbContext at design time. I manually added the code below and it's working now. It's just a temporary solution tho.
public AppDbContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<AppDbContext>();
optionsBuilder.UseSqlServer("Data Source=.;Initial Catalog=JwtTemplate;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False");
return new AppDbContext(optionsBuilder.Options);
}
Reference: https://stackoverflow.com/a/70559350

SSRS reports with .Net Core 3.1 MVC application

I am trying to display the SSRS report in a .Net Core 3.1 MVC application.
I tried to implement the approach mentioned in
https://alanjuden.com/2016/11/10/mvc-net-core-report-viewer/?unapproved=58532&moderation-hash=321d5350c96d2fcf83baa4c939bbdf53#comment-58532
public class ReportsController : AlanJuden.MvcReportViewer.ReportController
{
protected override ICredentials NetworkCredentials
{
get
{
//Custom Domain authentication (be sure to pull the info from a config file)
return new System.Net.NetworkCredential("username", "password");
//Default domain credentials (windows authentication)
//return System.Net.CredentialCache.DefaultNetworkCredentials;
}
}
protected override string ReportServerUrl
{
get
{
//You don't want to put the full API path here, just the path to the report server's ReportServer directory that it creates (you should be able to access this path from your browser:
return "https://YourReportServerUrl.com/ReportServer/ReportExecution2005.asmx";
}
}
public IActionResult ProcessReport()
{
var model = this.GetReportViewerModel(Request);
model.ReportPath = "reportPath";
return RedirectToAction("ReportViewer", model);
}}
but it is not working with the latest framework.
I am getting following error while running the project - Error screenshot
Any help is appreciated.
Thanks!
The same thing happened to me, in my case I needed to install the same package that tells you to install
Install-Package System.ServiceModel.Http -Version 4.1.0
or in the nuget look for the package System.ServiceModel.Http
I tried different workarounds with latest .NET Core including the one you mentioned from Alan Juden. However the easiest thing that worked for me is to create a plain .NET WebForms site using the Report Viewer control from Microsoft. It was still a lot of code but this is solid because the Report Viewer control has been around for many years.
In my case it is showing SSRS Report from Angular UI, but the same will work with MVC or any other Web UI because you will actually redirect/navigate to another url (WebForms aspx page).
More details here.

RelatedTo attribute not recognised, even after installation of Entity Framework 4.1

I am busy learning ASP.Net MVC and so I recently installed MVC 4 on Visual Studio 2010 Professional. I was trying this example:
http://www.luisrocha.net/2010/11/creating-composite-keys-using-code.html
But the RelatedTo attribute is not found by Visual Studio. I read on this question that this could be caused by Entity Framework 4.1 not being installed. I checked the version number of System.Data.Entity.dll and it gave version 4.0.0.0, runtime version v4.0.30319. So this seems to me to be version 4.0 of EF that is installed on my computer. I may be wrong on this though... so someone please correct me if I am.
I downloaded EF 4.1 from here and installed it, but the version numbers for System.Data.Entity.dll seem not to have changed and the RelatedTo attribute is still not working. Anyone know what is going wrong with the installation and how I could fix it?
UPDATE:
I installed Entity Framework using nuget as instructed on this site, and the console said it installed EntityFramework 5.0.0-rc, but the version of System.Data.Entity.dll seems to be unchanged.
No, I did not include using System.Data.Entity because intellisense did not tell me to include that. I did include System.ComponentModel.DataAnnotations and using System.ComponentModel.DataAnnotations.Schema because these were required by the Key and Column attributes. Intellisense asks me to "Generate class for 'RelatedTo'" and adding using System.Data.Entity does not change that.
Here is my code for those asking for it, although it is exactly the code from the tutorial that I linked to in the question:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
namespace Example
{
public class PlaylistTrack
{
[Key, Column(Order = 1)]
public int PlaylistId { get; set; }
[Key, Column(Order = 2)]
public int TrackId { get; set; }
[RelatedTo(ForeignKey = "PlaylistId")]
public Playlist Playlist { get; set; }
[RelatedTo(ForeignKey = "TrackId")]
public Track Track { get; set; }
}
}
Try installing new version of EF using Nuget. It will resolve all dependencies of EF and it will make sure you have the latest version. I don't know what is RelatedTo attribute supposed to be doing here. And see here in the data annotations section, the related to attribute is not in the EF4.1 release. But you can do the same thing like this.
[ForeignKey("PlaylistId")]
public Playlist Playlist { get; set; }
[ForeignKey("TrackId")]
public Track Track { get; set; }
EDIT
RelatedTo attribute is replaced by ForeignKey and InverseProperty attributes in EF 4.1 RC

MVC3 MvcScaffolding EF SqlCE SqlExpress - NO WORKY!

Not quite sure what's going on here but it seems as though Microsoft always comes out with the coolest frameworks (in theory) and then leaves no support. Anyone out there that can help me I will be VERY greatful. This one has had me stumped for two days now and I still cannot figure it out. Here's the setup:
Visual Studio 2010 Professional (or Express for that matter, I've tried both)
SQL Server Compact Edition 4 (or Express for that matter, I've tried both)
Create New Project, add new model (I called mine BlogModels.cs)
Add a new class called Post and give it properties as shown below...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
namespace MVC3BlogEngine.Models
{
public class Post
{
public int ID { get; set; }
[Required]
public string Title { get; set; }
[Required]
[DataType(DataType.MultilineText)]
public string Text { get; set; }
public DateTime PublishDate { get; set; }
}
}
Run project, browse to model (/Posts) and attempt to add a new post. If I enter more than say 128 characters, an exception is thrown:
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
So, what gives? I go look at the database that it created (which I think is the coolest thing since sliced bagels) and see that the column that it created was a nvarchar(128). So, my first thought was that even though I told it to use MultilineText as the datatype, it didn't generate a column properly (not good MS). So, I changed the datatype to text and tried again. No luck.
Anyone?
Well, it would seem that at last resort of removing the attribute of the datatype resolved the issue. The only reason I had it in there to start with was because of Scott Hanselman's video blog entry on creating an MVC3 Blog and he used the attribute in his example (November 2010) and MVC3 was still in development. So, FYI, DataType.MultilineText will not allow you to enter over 128 characters.

Problem with MVC3 AllowHtml attribute

I have a web app based on MVC3 (no beta or release candidate, RTM/RTW version) that has an action that accepts XML files for processing.
Of course, this seems evil to MVC because of possible attacks, so it doesn't allow it. Well, I try to put either AllowHtml on the model object as such:
public class XMLModel
{
[AllowHtml]
public string msg { get; set; }
}
Or I set ValidateInput to false on my action method such as this:
[ValidateInput(false)]
public ActionResult AddCDR(XMLModel model)
{
}
The reason for having a "strongly" typed model in the first place was that I originally tried to have a string value named "msg" as the action method parameter, but that always came back empty.
Now, when someone posts to this form, either on the same machine or from a networked computer, the msg field is always blank.
I have verified with WireShark that the data is actually in the request.
Now, one interesting thing. This should not be necessary with MVC 3. Yet it makes a slight difference.
If I add this to my web config:
<httpRuntime requestValidationMode="2.0" />
It works for requests originating from the local computer, but it does NOT work from another system.
I think the AllowHtml version seems elegant - if only it worked.
I have also found out about a bug in RC2 - again, this should not affect me, but I tried to add the following in Application_Start() anyway:
ModelMetadataProviders.Current = new DataAnnotationsModelMetadataProvider();
As expected, it makes no real difference.
Everything works as expected on my development computer (Win7x64, VS2010), but on the target system (Win2008R2x64, IIS7.5) the above problems are giving me a hard time.
Very important point to note: If I post to the action with no angle brackets, I get the form data as expected. As soon as the angle brackets show up, though, either my action isn't called at all, or it doesn't find the form data, neither in action method parameters or in for instance Request.Params["msg"] where it should be.
Any ideas to allow the XML through?
UPDATE
I've tried to work my way around this while waiting for anyone to come up with an answer here. I have not been able to solve it yet, but I have checked a few additional details;
First, I verified that the ASP.NET MVC 3 version installed on both my development computer and on the web server is the same; v3.0.20105.0 (according to Add/Remove programs).
The web application was actually created with the MVC3 beta, then converted to RC1 and RC2 as they came out, and finally to the RTM version. This meant I had to modify some code because of the ViewBag change. However, since I didn't know exactly what else had changed, I created a brand new MVC3 application with the RTM version, created a controller by the same name, with the same action method, taking a model object similar to the currently used one, renamed the old web app directory and put this new one in place. Exactly the same thing happens - i.e. the parameter with the AllowHtml attribute comes through with all content when the request is made from the local machine, but if it comes from a remote machine, then the HTML (XML actually) is stripped out.
There is no exception. I've installed Elmah and verified this - no exception occurs, my action method is apparently just called with anything looking like XML stripped out from the parameters to the method.
Needless to say, this is driving me crazy. I had some advice yesterday to look at the source code of MVC3, but unfortunately that doesn't really help me, as I can't see anything obviously wrong there, and I can't debug code on the server in question.
Any insights still highly desired, thanks! :)
I cannot reproduce this.
Model:
using System.Web.Mvc;
namespace MvcApplication3.Models {
public class XmlModel {
[AllowHtml]
public string msg { get; set; }
}
}
Controller:
using System.Web.Mvc;
using MvcApplication3.Models;
namespace MvcApplication3.Controllers {
public class HomeController : Controller {
public ActionResult Index() {
return View();
}
[HttpPost]
public ActionResult Index(XmlModel model) {
return View();
}
}
}
View:
#model MvcApplication3.Models.XmlModel
#using (Html.BeginForm()) {
<div class="editor-label">
#Html.LabelFor(model => model.msg)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.msg)
#Html.ValidationMessageFor(model => model.msg)
</div>
}
These were added to a default empty MVC 3 project. Everything posts fine. When I remove [AllowHtml], it generates the appropriate error message.
I am answering this myself because this was an obscure situation, and MVC3 was not the problem.
The system that POSTed data to my application was doing so with malformed data. In addition to that, I was told that they were also POSTing to an older MVC2 application that worked just fine - this was wrong, it turned out they were GETting in that case, and GET they happen to do correctly.
If anything, fairly thorough testing has confirmed that the AllowHtml attribute actually works very well. Never trust your input, tho. :)

Resources