asp.net mvc parameter binding string and guid - asp.net-mvc

I have a webapi controller with the following method signature:
public IHttpActionResult GetAttractions([FromUri] SearchAttractionRequest request)
The class SearchAttractionRequest looks like:
public class SearchAttractionRequest
{
public string Region { get; set; }
public string Category { get; set; }
public string Genre { get; set; }
}
This all works fine.
I am looking to create a new endpoint with same but this time the parameter will have fields that are guids so it will look like:
public class SearchAttractionGuidRequest
{
public Guid? Region { get; set; }
public Guid? Category { get; set; }
public Guid? Genre { get; set; }
}
And the new endpoint will be :
public IHttpActionResult GetAttractions([FromUri] SearchAttractionGuidRequest request)
Given that the parameters are coming from query string would the binding be able to bind? At the querystring level it's all strings. Ideally, I want to avoid creating a method with a new name.
Currently when i try this i get:
Multiple actions were found that match the request: GetAttractions

You can avoid creating a new method name by specifying different [Route] attributes for those methods.

Related

Pass complex data object in GET request to MVC controller action

I have model class as below:
public class HomeFilterModel {
public string CompanyName { get; set; }
public string Country { get; set; }
public DateRange Period { get; set; }
}
public class DateRange {
public DateTime? From { get; set; }
public DateTime? To { get; set; }
}
On client side, the data collected as below object:
{
"CompanyName":"",
"Country":"Canada",
"Period":{
"from":"2018-08-05T04:00:00.000Z",
"to":"2018-08-09T04:00:00.000Z"
}
}
It's converted to query string by $.param function and added to URL.
?CompanyName=&Country=Canada&Period%5Bfrom%5D=2018-08-05T04%3A00%3A00.000Z&Period%5Bto%5D=2018-08-10T04%3A00%3A00.000Z
The controller action is as below:
[HttpGet]
public ActionResult Index(HomeFilterModel filter) {
return View(filter ?? new HomeFilterModel());
}
The model data filter can get CompanyName and Country values correctly, but Period.From and Period.To are always NULL. I wonder if I have to make customized ModelBinder for this model class specifically? Or I should use different function other than $.param to construct query string in URL?
UPDATED:
If query string is changed to
?CompanyName=&Country=Canada&Period.from=2018-08-05T04%3A00%3A00.000Z&Period.to=2018-08-10T04%3A00%3A00.000Z
controller action can get all data correctly. So Period[from] is not acceptable by default model binder, while Period.from is.
Anyone has the simplest and best solution for this?

Viewmodel set up Aspt.net MVC 6

I'm having trouble understanding how to implement a ViewModel in Asp.net MVC, I have the following tables:
Form
ID, Data
Report
ID, FormID, Owner, Category, Status, SubmissionDate
ReportValues
ID, ReportID, Title, Value
I'm looking for a way to display and edit Report and ReportValues in the one ViewModel where ReportValues.ReportID = Report.ID
ReportValues will have multiple entries that relate to a Report.
I have had a look at similiar questions on here and tried following a tutorial ( http://techfunda.com/howto/262/list-data-using-viewmodel ) and coming up empty handed.
If you need any more information let me know and thanks in advance for any replies!
Your View Model is nothing more than a class. You can solve this many ways, but here's an example.
Create your 3 classes like you normally would.
public class Form
{
public int Id { get; set; }
public string Data { get; set; }
}
public class ReportValues
{
public int Id { get; set; }
public int ReportId { get; set; }
public string Title { get; set; }
public string Value { get; set; }
}
public class Report
{
public int Id { get; set; }
public int FormId { get; set; }
public string Owner { get; set; }
public string Category { get; set; }
public string Status { get; set; }
public DateTime SubmissionDate { get; set; }
}
Then, create your ViewModel class to include the three above classes like this.
public class ReportViewModel
{
public Form Form { get; set; }
public ReportValues ReportValues { get; set; }
public Report Report { get; set; }
}
In your view you can access your three classes and their properties as you would in your controller. Model.Form.Id
Depending on your data types, ReportValues will likely be a property of Report, but that's entirely up to your data structure. You will need to populate the classes using whatever method you want (Entity Framework, ADO, etc.) before you can pass them to your view and use them.

MVC4 Bind DataTable request parameters to action filter

I'm trying to implement server-side paging and sorting for jquery-datatable.
but the issue is I'm not able to bind data posted by datatable to my action model
to do sort and filter
Here is the data posted by jquery-datatable ajax request
draw:5
columns[0][data]:FirstName
columns[0][name]:FirstName
columns[0][searchable]:true
columns[0][orderable]:true
columns[0][search][value]:
columns[0][search][regex]:false
columns[1][data]:LastName
columns[1][name]:LastName
columns[1][searchable]:true
columns[1][orderable]:true
columns[1][search][value]:
columns[1][search][regex]:false
......
columns[n][data]:Position
columns[n][name]:Position
columns[n][searchable]:true
columns[n][orderable]:true
columns[n][search][value]:
columns[n][search][regex]:false
order[0][column]:1
order[0][dir]:desc
start:0
length:10
search[value]:
search[regex]:false
and my action method is:
public JsonResult GetGridData(GridFilter filter)
{ ....}
and my model classes are
public class GridFilter
{
public int draw { get; set; }
public List<ColModel> columns { get; set; }
public List<Order> order { get; set; }
public int start {get;set;}
public int length {get;set;}
public search search { get; set; }
}
public class ColModel
{
public string data { get; set; }
public string name { get; set; }
public string searchable { get; set; }
public string orderable { get; set; }
}
public class Order
{
public string dir { get; set; }
public string column { get; set; }
}
public class search
{
public string value {get;set;}
public string regex {get;set;}
}
How can I make data bind properly using default mvc model binders are a custom one.
Thanks
Make sure your model properties have the same data types as defined here.
Also you have gone one level too far with your models.They are sent as individual parameters so you don't need the GridFilter model, they should be received like so:
[HttpPost]
public JsonResult GetGridData(List<ColModel> columns, List<Order> order, Search search, int? start, int? length, int? draw)
{
}

Pass nested properties in asp.net mvc actionlink

My action accepts a model that looks like the following:
public class ClassListVM
{
public ClassListVM()
{
Filter = new ClassFilterModel();
}
public ClassFilterModel Filter { get; set; }
public PagedList<Class> Classes { get; set; }
}
public class ClassFilterModel
{
public int? TermId { get; set; }
public int? SubFormId { get; set; }
public int? FormId { get; set; }
}
public ActionResult Index(ClassListVM model)
{
model.Classes = classService.GetClasses(model.Filter);
return View(model);
}
Now I want to generate a url like this: /Classes?Filter.SubFormId=1. How do I get the Filter part into the url using this code:
go
As you can see, Filter cannot be used here.
Theoretically, you can build it this way:
go
Something like that; essentially, embed the query string into the client markup, and inject in only the parameters.

How should be my DTO object for ASP.Net MVC View?

i'd like to know, I have a application in asp.net mvc and nhibernate. I've read about that in the Views on asp.net mvc, shouldn't know about the Domain, and it need use a DTO object. So, I'm trying to do this, I found the AutoMapper component and I don't know the correct way to do my DTOS, for some domain objects. I have a domain class like this:
public class Entity
{
public virtual int Id { get; set; }
public virtual bool Active { get; set; }
}
public class Category : Entity
{
public virtual string Name { get; set; }
public virtual IList<Product> Products { get; set; }
public Category() { }
}
public class Product : Entity
{
public virtual string Name { get; set; }
public virtual string Details { get; set; }
public virtual decimal Prince { get; set; }
public virtual int Stock { get; set; }
public virtual Category Category { get; set; }
public virtual Supplier Supplier { get; set; }
public Product() { }
}
public class Supplier : Entity
{
public virtual string Name { get; set; }
public virtual IList<Product> Products { get; set; }
public Supplier() { }
}
I'd like to get some example of how can I do my DTOs to View ? Need I use only strings in DTO ? And my controllers, it should get a domain object or a DTO and transform it on a domain to save in repository ?
Thanks a lot!
Cheers
There is no guidelines on this matter and it depends on your personal chice. I have few advices that have proven useful in practice:
1. Use flat DTOs - this means that the properties of the DTO must be as primitive as possible. This saves you the need for null reference checking.
For example if you have a domain object like this:
public class Employee
{
prop string FirstName{get; set;}
prop string LastName{get; set;}
prop Employee Boss{get; set;}
...
}
And you need to output in a grid a list of employees and display information for their 1st level boss I prefer to create a DTO
public class EmployeeDTO
{
prop string FirstName{get; set;}
prop string LastName{get; set;}
prop bool HaveABoss{get;set}
prop string BossFirstName{get; set;}
prop string BossLastName{get; set;}
...
}
or something like this (-:
2. Do not convert everything to sting - this will bind the DTO to a concrete view because you'll apply special formatting. It's not a problem to apply simple formatting directly in the view.
3. Use DTOs in your post actions and than convert them to domain objects. Usually controller's actions are the first line of deffence against incorrect data and you cannot expect to be able to allways construct a valid domain object out of the user's input. In most cases you have to do some post-processing like validation, setting default values and so on. After that you can create your DTOs.

Resources