Swagger not loading - Failed to load API definition: error undefined message - swagger

As I tried to change one public method to private. The issue will be gone.
But when I defined the public method on both method as the below controller code, it will bring up the error.
Anyone help/advice if possible would be really appreciate
WEBLABController.cs
[Route("api/SearchLABResults")]
[HttpPost]
public async Task<IActionResult> SearchLABResults([FromBody] SP_GET_LABResult_Overview.input data)
{
IActionResult response = Unauthorized();
......
return response;
}
AuthenticationController.cs
[Route("api/GenerateToken")]
[HttpPost]
public async Task<IActionResult> GenerateToken([FromBody] AuthenticationModel.input data)
{
IActionResult response = Unauthorized();
......
return response;
}

If you scroll down the swagger view, You see that every model you are using is shown there. Swagger needs that those names be unique.
SP_GET_LABResult_Overview.input and AuthenticationModel.input are both generate input schema and that cause InvalidOperationException.
Try to change one of the input classes to something else or change their schema on the fly like this.
services.AddSwaggerGen(options =>
{
options.CustomSchemaIds(type => type.ToString());
});

Related

ASP .NET MVC - getting null querystring values in controller

I'm trying to reach a controller method by providing some url parameters :
http://localhost/GoTo/Index?topic=test
Here's the method I want to reach :
public ActionResult Index(string topic)
{
//do some stuff
}
Problem is, the topic parameter in the method is always null. I also tried to check what I got in Request.QueryString collection, but it's empty.
Any lead/explanation would be appreciated.
EDIT : Screenshot requested :
Please try this it's working for me check below screenshot
Just call you're URL like this
http://localhost/GoTo?topic=test
public class TestingController : Controller
{
// GET: Testing
public ActionResult Index(string topic)
{
return View();
}
}

asp.net core validation after filters

I want to run some custom logic for all APIs (asp.net core) that we have in our service before model validation but after model binding. Is this possible? I tried an ActionFilter but it gets called after validation. Resource filter also does not work for us. Appreciate your help.
Web API controllers don't have to check ModelState.IsValid if they have the [ApiController] attribute. In that case, an automatic HTTP 400 response containing issue details is returned when model state is invalid.
One way to achieve what you want is to suppress this behavior.
Add the following code to ConfigureServices:
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressModelStateInvalidFilter = true;
});
Then you can add your code to the filter - eg:
public class SampleActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// do something before the action executes
if(context.ActionArguments != null && context.ActionArguments.Count > 0)
{
//WARNING - you should add "safe" code to access the dictionary
//I have hardcoded the parameter name (data) here for sample only.
var model = context.ActionArguments["data"];
}
}
public void OnActionExecuted(ActionExecutedContext context)
{
// do something after the action executes
}
}
of course you need to apply the filter as well - in the example case below, I have applied it globally. You can be more specific if you want.
services.AddMvc(
options => options.Filters.Add(new SampleActionFilter())
).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
In your controller code, you can also further use the TryValidateModel method if you want, like so:
[Route("api/[controller]")]
[ApiController]
public class ProcessController : ControllerBase
{
[HttpPost]
public IActionResult Contact(FormDataModel data)
{
bool validated = TryValidateModel(data);
if (!ModelState.IsValid)
{
ModelState.AddModelError("", "Id cannot be empty..");
return Ok();
}
return Ok();
}
}
Hope this helps to solve your problem.

Attribute Routing related issue using Asp.Net MVC 5 and Web API 2

I am trying to change my existing web api controller from convention based routing to attribute routing, so I changed my existing code to the following:
[Route("api/Visitors")]
public IQueryable<Visitor> GetVisitors()
{
return db.Visitors;
}
and GET method works great, but when I am applying same attribute to POST method like:
[Route("api/Visitors")]
[ResponseType(typeof(Visitor))]
public async Task<IHttpActionResult> PostVisitor(Visitor visitor)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Visitors.Add(visitor);
await db.SaveChangesAsync();
return CreatedAtRoute("DefaultApi", new { id = visitor.Id }, visitor);
}
It is throwing following exception:
An exception of type 'System.Net.Http.HttpRequestException' occurred in System.Net.Http.dll but was not handled in user code
Additional information: Response status code does not indicate success: 500 (Internal Server Error).
at this line resp.EnsureSuccessStatusCode(); of the following method:
public bool SaveVisitor(Visitor visitor)
{
HttpResponseMessage resp = client.PostAsJsonAsync<Visitor>("/api/Visitors", visitor).Result;
resp.EnsureSuccessStatusCode();
if (resp.StatusCode == System.Net.HttpStatusCode.Created)
return true;
else
return false;
}
client is an instance of HttpClient at class level.
I am not able to get the reason behind this exception. What am I missing here? If I remove attribute routing data is saved/retrieved as expected. I am referring to the article on Attribute Routing
Please help.
Try adding the [HttpPost] attribute to your "Post" endpoint. As follows:
[Route("api/Visitors")]
[HttpPost]
[ResponseType(typeof(Visitor))]
public async Task<IHttpActionResult> PostVisitor(Visitor visitor)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Visitors.Add(visitor);
await db.SaveChangesAsync();
return CreatedAtRoute("DefaultApi", new { id = visitor.Id }, visitor);
}
Another possibility... it seems from your code that your controller class might be called "VisitorsController". Visitors being plural.
Maybe try to add an 's' to your post method?
public async Task<IHttpActionResult> PostVisitors(Visitor visitor)

MVC: trying to understand where ActionResult sends it's data

I have been trying to understand an online tutorial and I am stumped.
Can someone please tell me where the text "Hello" is sent to? Is the message sent directly to the browser without being placed on a page?
public class GoHomeController : Controller
{
public string Index()
{
return "Hello";
}
}
How's this? Your controller action needs to have a return type of ActionResult, there are many subclasses of this class that allow for various types of responses however you can always influence with brute force if you like. For example"
public ActionResult Index()
{
Response.Write("hello world");
return null;
}
The above code writes to the Response stream directly, in my example I return a null. This indicates no ActionResult is needed to be performed by the MVC system, typically this is where the View is specified, the View will be read, parsed and written to the Response stream as well.
But typical controller actions do have return values, for example here is how I could return JSON, remember the View is just an abstraction to allow you to control what is written to the Response stream.
public ActionResult Index()
{
return Json( new { Message="Hello world"});
}
And then there is the typical ActionResult that directs the output to a .cshtml file:
public ActionResult Index()
{
return View();
}
This will write to the Response stream using the Index.cshtml file tied to this controller namespace or I could specify the name of the .cshtml:
public ActionResult Index()
{
return View("HelloWorld"); //<-- looks for HelloWorld.cshtml
}

MVC 4 Routing , Get/Post requests handling

I'm faced with the following problem :
I have a controller with lets say the following actions:
[HttpGet]
public ActionResult Index()
{
var viewModel = new IndexViewModel();
return View("Index", viewModel);
}
[HttpPost]
public void ExportToExcell(LeadsViewModel model)
{
// Export to excell code goes here
}
The problem is the following:
The User enters on Index page with this URL : /Controller/Index
Then the user submits the form to Action ExportToExcel
Data is exported to Excel( file downloaded ) and it's okay.
The URL becomes /Controller/ExportToExcell
Then when I am clicking "Enter" I am going To /Controller/ExportToExcell but with GET
and of course falling with Page Not Found, the question is how properly to Deal with this in MVC
Don't use void as returned type of your post action, use an ActionResult
[HttpPost]
public ActionResult ExportToExcell(LeadsViewModel model)
{
// Export to excell code goes here
return RedirectToAction("Index");
}
I believe that your problem is that you aren't returning a FileResult, and the browser will redirect you to your post path. Can't test it right now, but I believe the following should work.
[HttpPost]
public ActionResult ExportToExcell(LeadsViewModel model)
{
// Generate the Excel file into a MemoryStream for example
// Return a FileResult with the Excel mime type
return File(fileStream, "application/vnd.ms-excel", "MyExcelFile.xls");
}
Check FileResult and Controller.File for more details.
As a note, I'm not completely sure if that's the mime type for an Excel file, but if you say you are already downloading the file, your probably already have it :)
You must return ActionResult instead of void.
public ActionResult ExportToExcel(PagingParams args)
{
var data = new StudentDataContext().Student.Take(200).ToList();
return data.GridExportToExcel<Student>("GridExcel.xlsx", ExcelVersion.Excel2007, args.ExportOption);
}
Please check the link: Export Action

Resources