I have the following sudo-code
class viewModel
{
public ICollection<modelA> parentModel
public modelC formModel
}
class modelA
{
public int ID {get;set;}
public virtual Icollection<modelB> {get;set;}
}
class modelB
{
public int ID {get;set;}
public string SomeString {get;set;}
public virtual modelA ModelA {get;set;}
}
class modelC
{
public int ModelAID {get;set;}
public string SomeString {get;set;}
}
So. the view model contains a collection of As. Each A contains a collection of Bs and there is a separate model for posting back as a form: the form will be repeated on the page, once in each instance of A with the A.ID passed in to ModelAID as a hidden field. Only one form posting is allowed on the page, The id of the form fields are formModel.ModelAID and .formModel.SomeString as they are derived from the non-parent element of the viewModel.
How do I get the ActionResult to bind only to formModel?
[HttpPost]
Public ActionResult Input(formModel vm)
{
... by default the view model being passed back is full VM, I only want the formModel so the post signature does not match
}
You can try something like
public ActionResult Input([Bind(Prefix = "formModel ")]modelC model)
{
}
Related
I've build custom IOperationFilter based in this article.
It works ok with simple examples like this:
public async Task<IActionResult> GetModels([FromQuery]Parameters parameters)
{
...
}
public class Parameters
{
public int PageSize {get;set;}
public int PageNumber {get;set;}
}
But when I try to set complex parameters like this:
public async Task<IActionResult> GetModels([FromQuery]ComplexParameters parameters)
{
...
}
public class Parameters
{
public int PageSize {get;set;}
public int PageNumber {get;set;}
}
public class ComplexParameters
{
public string Contains {get;set;}
public Parameters Pagination {get;set;}
}
I got problem that swagger creates RequestUrl with brackets for nested class:
https://Url/Path?contains=string&pagination[pageSize]=0&pagination[pageNumber]=0
I have a model class. That class contains multiple properties , list of custom class and list of formfile data. I need to create post request for this model using Asp.net Core.
Model Class
public class TenoModel
{
[Key]
public int Id { get; set; }
public DateTime Date { get; set; }
public float Salary { get; set; }
[Required]
public string User { get; set; }
public List<IformFile> files {get;set;}
public List<Employee> employees{get;set;}
}
Custom class for employee
public class Employee
{
public int Id {get;set;}
public string Name {get;set;}
public double Salary {get;set;}
}
HttpPost request:
[HttpPost("CreateTeno")]
[Consumes('multipart/form-data']
public async Task<IActionResult> CreateTeno([FormFile] TenoModel model)
{
..... save the model data to teno database
}
When I execute the HttpPost request on swagger Formfile data and some property data come to incoming request on CreateTeno method. I fill the Employee object also in swagger. but that data not coming in my CreateTeno method. List of Employee data count zero. How to pass model class with multiple properties, List of IformFile and multiple list customclass in HTTP post request. Give a sample example.
You'll have to change the signature of your controller method like this:
public async Task<IActionResult> CreateTeno([FromForm] TenoModel model)
Tested with Postman like this
Please note that you have a syntax error here: [Consumes('multipart/form-data'], should be [Consumes("multipart/form-data")]
I'm looking for a way to have more than one action method with the same name in controller without changing Url (route).
[HTTPPost]
Public ActionResult Method1 (Dto1 param)
{
}
[HTTPPost]
Public ActionResult Method2 (Dto2 param)
{
}
[HTTPPost]
Public ActionResult Method3 (Dto3 param)
{
}
This throws error -
Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints
Dto1, Dto2 and Dto3 derive from a base Dto, each have properties specific to different request methods. I am trying to avoid having a single method with a common Dto which will require multiple validations such as validating mandatory fields based on the value of other fields, etc. If we can have 3 different Post methods with different Dtos, it would makes things much easier
Adding Dtos (Simplified)
public class BaseDto
{
public string CommonProp1 { get; set; }
public string CommonProp2 { get; set; }
}
public class Dto1: BaseDto
{
public enumType Type = enumType.Type1;
public string Property1 { get; set; }
}
public class Dto2 : BaseDto
{
public enumType Type = enumType.Type2;
public string Property2 { get; set; }
}
public class Dto3 : BaseDto
{
public enumType Type = enumType.Type3;
public string Property3 { get; set; }
}
You can use Routes or calling a private method from the three above methods, you shouldn't do this as you want. I think your problem is more deep.
But.... if you still want it, here is a workaround.
Instead of receiving an object, receive a string with json content and parse the object.
But you will have to have a property inside the "json object" or another parameter that defines you wich object it is (Dto1, Dto2 or Dto3). In any case will be the same that use different routes or methods because objects are different.
[HTTPPost]
Public ActionResult Method (string param)
{
//Decode your string called param with JSON with a property inside
}
or
[HTTPPost]
Public ActionResult Method (string param, int type)
{
//Decode your string called param with JSON switching "type" as 1, 2 or 3
}
UPDATE after your update:
I suggest you receive BaseDto and the type in other parameter.
[HTTPPost]
Public ActionResult Method (BaseDto param, int type)
{
}
I have a very simple ASP.NET MVC4 page. It's rendering an edit form for the CustomerModel. The form displays correctly, but when I hit edit and post back, the model isn't being bound. Instead, all the properties of the CustomerModel are left at their defaults. Note that the correct controller method is being invoked, so that's not the issue.
I can see the form values with matching names to the model properties (Id, Name, Description), but the model doesn't have them set.
Ideas?
Here is the model:
public class CustomerModel
{
[Required]
public Guid Id;
[Required]
public string Name;
[Required]
public string Description;
}
And here is the relevant controller method:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(CustomerModel customerModel)
{
if (ModelState.IsValid)
{
//...Do stuff
return RedirectToAction("Index");
}
return View(customerModel);
}
Finally, here is a screen shot of the form collection with the populated values:
Your model has public fields but not public properties, these are not the same.
Change to:
public class CustomerModel
{
[Required]
public Guid Id {get; set;}
[Required]
public string Name {get; set;}
[Required]
public string Description {get; set;}
}
The default MVC model binder will work with properties, not fields.
More about this here - http://rightbrainleft.net/2011/02/default-mvc-model-binder-doesnt-like-fields/
Using NHibernate 2.1, I'm trying to project an entity and its child collection into a DTO. My entity looks like this..
public class Application
{
public int Id {get;set;}
public string Name {get;set;}
public List<ApplicationSetting> Settings {get;set;}
// A bunch of other properties that I don't want in the DTO
}
public class ApplicationSetting
{
public int Id {get;set;}
public string Name {get;set;}
public string Code {get;set;}
// A bunch of other properties that I don't want in the DTO
}
My DTO looks like this..
public ApplicationDto
{
public int Id {get;set;}
public string Name {get;set;}
public List<ApplicationSettingDto> Settings {get;set;}
}
public class ApplicationSettingDto
{
public int Id {get;set;}
public string Name {get;set;}
public string Code {get;set;}
}
My code to select JUST the Application and project it is this (using Nhibernate 2.1 and nhLambdaExtensions)
var applicationAlias = new Application();
var criteria = Session
.Add<Application>(a => a.Id == id);
int? Id = null;
string Name = null;
criteria
.SetProjection
(
Projections.Distinct(
Projections.ProjectionList()
.Add(LambdaProjection.Property<Application>(a => a.Id).As(() => Id))
.Add(LambdaProjection.Property<Application>(a => a.Name).As(() => Name))
)
);
criteria.SetResultTransformer(Transformers.AliasToBean(typeof(ApplicationDto)));
var contract = criteria.UniqueResult<ApplicationDto>();
My question is, how do I project just SOME of the properties from the ApplicationSettings entity to the ApplicationSettingsDto child collection?
I think you might need to do a MutiQuery and bring together the DTO parents and children yourself.