String array in query parameters swagger - asp.net-core

I'm working on a project where there is an endpoint that receives a list of strings in the parameter, as shown in the code below:
public class PaymentFilter
{
public List<string> Status {get; set; }
}
[HttpGet]
public IActionResult Get([FromQuery] PaymentFilter filter)
{
...
}
However, in the swagger interface the status list is not reflected, as shown in the image:
How do I enable entries for the status list?

Click Try it out button and click Add string item then you can add
parameter

Related

HttpPost [FromForm] also accepts query params

To my despair, the below URL binds successfully and returns 200 OK.
https://myfakedomain.com/api/Submit?Email=test%40test.com&Name=fakeName
I just learned that my ASP.NET Core API accepts parameters to be submitted using query-strings. I do not want to allow users to submit sensitive data as part of the URL. Instead, I want to enforce my users to submit their info using FormData.
My endpoint looks like this:
[HttpPost]
public async Task<IActionResult> Register([FromForm] RegisterDTO registerDTO)
{}
public class RegisterDTO
{
public string Email { get; set; }
public string Name { get; set; }
}
I might add that submitting FormData also binds successfully.

using a class method in MVC4

I just start do work on MVC4 Asp.Net
I have this class in my models
namespace PhoneBook.Models
{
public class User
{
public string Username { get; set; }
public string Password { get; set; }
public static String writeasd(){
return "asd";}
}
I have this method in my controller:
public ActionResult Main()
{
ViewBag.Username = Request.Form["username"];
ViewBag.Password = Request.Form["password"];
var user = new User()
return View(user);
}
However when I tried to call this method from my view like this:
#User.writeasd()
It gives error. What is the problem? Can you help me?
Note : I have #using PhoneBook.Models in the beginning of my view
When using a strongly typed view as you are there, you need two things.
One is a model directive
#model PhoneBook.Models.User
Then you can reference your model using the Model property of the view page.
So in your instance, you would use
#Model.writeasd()
HTH

Pass Url Parameters to Action by Model in ASP.NET MVC 4

I want to assign my url parameters to Model properties, passed as a parameter to the associated Action. For example;
Say, my url is http://www.example.com/Item/Index?color=red&size=50
My action inside the controller is like below:
public class ItemController : Controller
{
public ActionResult Index(MyModel myModel)
{
//
return View(myModel);
}
}
I want to configure the model or whatever necessary so that my model takes the color and size as field values. The following didn't work:
public class MyModel
{
[Display(Name = "color")]
public string Color{ get; set; }
[Display(Name = "size")]
public string Size{ get; set; }
}
What would be the correct way to solve the problem?
Thanks for any suggestion.
Update
Well, yes! The code above would work correctly, because Url parameter names are the same as model property names. I should explain my problem exactly as I encounter for the next time, sorry.
I must correct a part of my question to make it clear. The url should have been: http://www.example.com/Item/Index?c=red&s=50 to detect the problem.
If the url is like that, the code would not work. Because Url parameters don't have the same name as Model properties.
Updated model is below:
public class MyModel
{
[Display(Name = "c")]
public string Color{ get; set; }
[Display(Name = "s")]
public string Size{ get; set; }
}
Try adding [FromUri] in front of the parameter.
public class ItemController : Controller
{
public ActionResult Index([FromUri] MyModel myModel)
{
// do something
return View();
}
}
debugging the issue
Here are some suggestions in debugging the issue, as it should work out of the box.
try binding to primitive types
public class ItemController : Controller
{
public ActionResult Index(string color, string size)
{
// do something
return View();
}
}
Try reading out of the request object directly
var size = this.Request["size"];
If either of those work there is an issue with your model binding.
Update
If you want to have the query string parameters different to the model in MVC you'll need to have a custom model binder. Take a look at Asp.Net MVC 2 - Bind a model's property to a different named value and http://ole.michelsen.dk/blog/bind-a-model-property-to-a-different-named-query-string-field.html which extends the answer a little.
https://github.com/yusufuzun/so-view-model-bind-20869735 has an example with some html helpers that could be useful.

Web API Help Page with template classes

I have a ASP.NET Web API which returns a template class but I can't get the Web API Help Page to provide documentation for the return type correctly.
Let's say I have the following Model classes:
public class MyType<T>
{
/// <summary>A list of T</summary>
public List<T> MyList { get; set; }
}
public class Foo
{
/// <summary>Bar string</summary>
public string Bar { get; set; }
}
and my API action looks as follows
[ResponseType(typeof(MyType<Foo>))]
public IHttpActionResult Get()
{
return Ok<MyType<Foo>>(new MyType<Foo>());
}
The resulting Web API Help Page then declares that the Get action returns a MyTypeOfFoo and do not provide the XML documentation for MyType, it just lists the parameters it contains. Probably because it don't understand that MyTypeOfFoo is the same as MyType<Foo>.
Are there any known solutions to this problem?
Update
Creating a pseudo-class and returning it instead does not work either. E.g.
/// <summary>My Foo Type</summary>
public class MyFooType : MyType<Foo>
{
}
[ResponseType(typeof(MyFooType)]
public IHttpActionResult Get()
{
return Ok<MyFooType>(new MyFooType());
}
The documentation output for the above code lacks the comments available on the inherited properties.

Why does ASP.NET MVC assumes that view will have matching input and output types?

ASP.NET MVC (or rather Html.Helpers and base page implementation) assumes that there will be one type for both rendering and posting (namely Model).
This is a violation of ISP, isn't it?
I am tempted to derive my Edit views (those that have different render-data, and post-data) from a custom EditPageBaseView<TViewModel, TFormData>.
The problem is I want my validation and post work against FormData instance (stored inside ViewModel), but MVC assumes that entire ViewModel will be POSTed back.
Is there an OOB way to facilitate that? (I didn't find one if there is).
Is it a bad idea (in concept) to have separate data types for different operations exposed by a service (a view in this case).
I tend to follow the CQRS model when constructing my view models. All rendering is done with ViewModel classes and all posting back is done with Command classes. Here's a contrived example. Let's say we have a View with a small form for creating users.
The ViewModel and Command classes looks like this:
public abstract class ViewModel {}
public abstract class Command: ViewModel
public class CreateUserViewModel : ViewModel
{
public string Username { get; set; }
public string Password { get; set; }
public string PasswordConfirm { get; set; }
}
public class CreateUserCommand : Command
{
public string Username { get; set; }
public string Password { get; set; }
public string PasswordConfirm { get; set; }
}
The UserController creates a CreateUserViewModel as the model for the Get request and expects a CreateUserCommand for the Post request:
public ActionResult CreateUser()
{
// this should be created by a factory of some sort that is injected in
var model = new CreateUserViewModel();
return View(model);
}
[HttpPost]
public ActionResult CreateUser(CreateUserCommand command)
{
// validate and then save the user, create new CreateUserViewModel and re-display the view if validation fails
}
Model binding takes care of ensuring that the properties of the Posted CreateUserCommand are populated properly, even though the Get View is bound to a CreateUserViewModel.
They don't have to match, but they do match by default.
If you don't want them to match, you can specify a different model in your Form or ActionLink:
Example of a Mismatch using Razor and C#:
Index.chtml:
#model FirstModel
<div>
#using (Html.BeginForm("Action", "ControllerName", new { ParameterName = new SecondModel { First = "First", Second = "Second" } }, FormMethod.Post)) {
<input type="submit" value="Submit Button" />
}
</div>
The Controller:
public class ControllerName : Controller {
public ActionResult Index() {
return View(new FirstModel());
}
public ActionResult Action(SecondModel ParameterName) {
return View() // Where to now?
}