When I am passing a single object like below then it is working as per below image
[HttpPost]
public async Task<ActionResult> Post([FromForm] MyModel Details)
{
}
but when I am passing the List of the object to API then it is not working. option to upload a file is not visible. and if I entered any values in the array then also I am getting count 0 for details.
[HttpPost]
public async Task<ActionResult> Post([FromForm] List<MyModel> Details)
{}
I want to pass the List of images and descriptions to API. How can I achieve it?
Thanks in advance!
You need custom model binding for the list model . Here is a similar demo:
custom model binding code:
public class MetadataValueModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
throw new ArgumentNullException(nameof(bindingContext));
var values = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (values.Length == 0)
return Task.CompletedTask;
var options = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true };
var deserialized = JsonSerializer.Deserialize(values.FirstValue, bindingContext.ModelType, options);
bindingContext.Result = ModelBindingResult.Success(deserialized);
return Task.CompletedTask;
}
}
Add the model binder to the model class:
public class MasterDTO
{
public string Comments { get; set; }
public IFormFile File { get; set; }
public List<DetailDTO> Details { get; set; }
public MasterDTO()
{
this.Details = new List<DetailDTO>();
}
}
[ModelBinder(BinderType = typeof(MetadataValueModelBinder))]
public class DetailDTO
{
public Int64 ElementId { get; set; }
public double LowerLimit { get; set; }
public double HigherLimit { get; set; }
public string Status { get; set; }
public string UserAuthorization { get; set; }
public DateTime? AutorizationDate { get; set; }
}
controller/action
[HttpPost]
public async Task<IActionResult> CreateProjectLimit([FromForm] MasterDTO masterDto)
{
//...
return Ok();
}
You can just use postman to pass the list of images and Descriptions to API
Below is the right answer. we can use Postman to pass images in the array as shown below.
I'm trying to access data with DAL2 in DotNetNuke. When I use the repository.Get() to get all fields of a certain table I sometimes get this error:
'Value cannot be null. Parameter name: con'
public IEnumerable<SitesProvince> GetAll()
{
using (var ctx = DataContextContent.Instance())
{
var rep = ctx.GetRepository<SitesProvince>();
return rep.Get();
}
}
Model:
[TableName("Sites_Province")]
[PrimaryKey("Sites_Province_No")]
[Cacheable("Sites_Province", CacheItemPriority.Default, 20)]
[Scope("Sites_Province_No")]
public class SitesProvince
{
public int Sites_Province_No { get; set; }
public string BU { get; set; }
public string Province { get; set; }
}
What could be the problem? In some queries it works and some don't and I don't see any difference between the methods.
I found this but I have no contracts:
http://clraddins.codeplex.com/discussions/24568
I solved this problem by adding an empty constructor to my model. Now everything works fine.
My application has the following classes:
public class Widget {
public virtual int Id { get; set; }
public virtual WidgetType Type { get; set; }
public virtual string Parameters { get; set; }
}
public class WidgetType {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string ParametersAssembly { get; set; }
public virtual string ParametersClass { get; set; }
}
Now if i'd like to update the Parameters for a particular widget i would say something like:
// Get the widget
var widget = GetWidget(1);
// Create an instance of the type parameters class
var parameters = Activator.CreateInstance(Assembly.LoadFrom(Server.MapPath("~/bin/"
+ widget.Type.ParametersAssembly + ".dll")).GetType(widget.Type.ParametersClass));
... Code here to update the parameters
widget.Parameters = new XmlSerializer(parameters.GetType()).Serialize(parameters);
I have to do the reverse when i wish to get the parameters. You can imagine this becomes quite tedious. I was wondering if it was possibly to automatically do this?
I've been looking at the IUserType interface. I found an article which is kind of similar. However my problem is a little more complicated as my type changes based on the type of the widget.
I'd appreciate it if someone could let me know if this is possible and possibly how it could be achieved. Thanks
an easy way
public class Widget
{
public virtual int Id { get; set; }
public virtual WidgetType Type { get; set; }
private string _serializedParameters;
private virtual string SerializedParameters {
get
{
return new XmlSerializer(Parameters.GetType()).Serialize(Parameters);
}
set
{
_serializedParameters = value;
// code to deserialize the Parameters and set to Parameters
var ptype = Assembly.LoadFrom(Server.MapPath("~/bin/" + widget.Type.ParametersAssembly + ".dll")).GetType(widget.Type.ParametersClass);
Parameters = Activator.CreateInstance(ptype);
}
}
private object _parameters;
public virtual object Parameters
{
get
{
if (_parameters == null)
_parameters = Activator.CreateInstance(Assembly.LoadFrom(Server.MapPath("~/bin/" + widget.Type.ParametersAssembly + ".dll")).GetType(widget.Type.ParametersClass));
return _parameters;
}
set { _parameters = value; }
}
}
it can't be in the Parameters property because then you have to get -> alter -> set instead of get -> alter. But you are right that building the parameters object should go in the getter of Parameters because only there we can be sure to have the WidgetType loaded
it is essentially the same as a UserType except that we know that WidgetType is there
I am calling on a WCF Data Services v3 Odata service.
I am having trouble getting my collection filled in the below example. I am able to get a json string of the 3 people, but if I try and get a custom collection filled, the collection has a count = 0.
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.BaseAddress = new Uri("http://localhost:7500/Wcf1.svc/People");
HttpResponseMessage resp = client.GetAsync("").Result;
string jsonString = resp.Content.ReadAsStringAsync().Result;
List<Person> personCollection = resp.Content.ReadAsAsync<List<Person>>().Result;
jsonString has 3 people in it.
personCollection has a count = 0.
the jsonString looks like this:
{"d":[
{"__metadata":{"id":"http://localhost:7500/Wcf1.svc/People(1)",
"uri":"http://localhost:7500/Wcf1.svc/People(1)",
"type":"WcfService1.Person"},
"ID":1,"Fname":"Fred","Lname":"Peters","Address1":"123 Main"},
{"__metadata":{"id":"http://localhost:7500/Wcf1.svc/People(2)",
"uri":"http://localhost:7500/Wcf1.svc/People(2)",
"type":"WcfService1.Person"},
"ID":2,"Fname":"John","Lname":"Smith","Address1":"123 Oak"},
{"__metadata":{"id":"http://localhost:7500/Wcf1.svc/People(3)",
"uri":"http://localhost:7500/Wcf1.svc/People(3)",
"type":"WcfService1.Person"},
"ID":3,"Fname":"Tom","Lname":"Anders","Address1":"123 Hill St."}]}
I must be doing something wrong, please point out my error if you can.
Thanks.
Terrence
Your content is not a List<Person>
Paste your Json into json2csharp and you'll see it.
To get a better overview what your response content is, download Json Viewer - this is a screenshot of your data:
As you can see: the Persons are a property of the Json root object.
If you wanted to use your code from above, the Json should have to look like this (or you need to access the data in the given structure mapping you classes according to the Json):
[{"__metadata":{"id":"http://localhost:7500/Wcf1.svc/People(1)",
"uri":"http://localhost:7500/Wcf1.svc/People(1)",
"type":"WcfService1.Person"},
"ID":1,"Fname":"Fred","Lname":"Peters","Address1":"123 Main"},
{"__metadata":{"id":"http://localhost:7500/Wcf1.svc/People(2)",
"uri":"http://localhost:7500/Wcf1.svc/People(2)",
"type":"WcfService1.Person"},
"ID":2,"Fname":"John","Lname":"Smith","Address1":"123 Oak"},
{"__metadata":{"id":"http://localhost:7500/Wcf1.svc/People(3)",
"uri":"http://localhost:7500/Wcf1.svc/People(3)",
"type":"WcfService1.Person"},
"ID":3,"Fname":"Tom","Lname":"Anders","Address1":"123 Hill St."}]}]
Update:
You should be able to parse your initially posted Json like this:
var json = JsonValue.Parse(response.Content.ReadAsStringAsync().Result);
var arr = json["d"];
var contact1 = arr[0];
var fname = result1["Fname"];
I have done a blog post on JsonValue and JsonArray recently. It's server side, but it should point you the direction.
2nd Update:
Using the classes from the json2csharp.com output, you can do this:
public class Metadata
{
public string id { get; set; }
public string uri { get; set; }
public string type { get; set; }
}
public class D
{
public Metadata __metadata { get; set; }
public int ID { get; set; }
public string Fname { get; set; }
public string Lname { get; set; }
public string Address1 { get; set; }
}
public class RootObject
{
public List<D> d { get; set; }
}
Usage:
var root = resp.Content.ReadAsAsync<RootObject>().Result;
var persons = root.d;
var person1 = persons[0];
I have an index that works great when I query it using the .Net client API with a server based RavenDb.
However, if I change the RavenDb to an embedded type then I cannot query the index directly unless I first query the document that the index uses.
For instance if I have the following document objects which reside as separate collections in the RavenDb:
private class TestParentDocument
{
public string Id { get { return GetType().Name + "/" + AggregateRootId; } }
public Guid AggregateRootId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
private class TestChildProductFlagDocument
{
public string TestParentDocumentId { get; set; }
public short ProductFlagTypeId { get; set; }
}
Then I have the following object which represents the output document that the index maps to:
private class TestJoinIndexOutput
{
public string TestParentDocumentId { get; set; }
public string Name { get; set; }
public short ProductFlagTypeId { get; set; }
}
Here is the index definition:
private class TestJoinIndex : AbstractIndexCreationTask<TestChildProductFlagDocument, TestJoinIndexOutput>
{
public TestJoinIndex()
{
Map = docs => from doc in docs
select new
{
TestParentDocumentId = doc.TestParentDocumentId,
ProductFlagTypeId = doc.ProductFlagTypeId
};
TransformResults = (database, results) =>
from result in results
let parentDoc = database.Load<TestParentDocument>(result.TestParentDocumentId)
select new
{
TestParentDocumentId = result.TestParentDocumentId,
ProductFlagTypeId = result.ProductFlagTypeId,
Name = parentDoc.Name
};
}
My code to call the index looks like so:
var theJoinIndexes = ravenSession.Query<TestJoinIndexOutput, TestJoinIndex>().ToList();
This returns almost immediately and fails unless I do the following:
var theParentDocuments = ravenSession.Query<TestParentDocument>().ToList();
var theJoinIndexes = ravenSession.Query<TestJoinIndexOutput, TestJoinIndex>().ToList();
My Ravendb embedded definition looks like so:
docStore = new EmbeddableDocumentStore
{
UseEmbeddedHttpServer = false,
RunInMemory = true
};
docStore.Configuration.Port = 7777;
docStore.Initialize();
IndexCreation.CreateIndexes(typeof(TestJoinIndex).Assembly, docstore);
You aren't waiting for indexing to complete, call WaitForNonStaleResultsAsOfNow