locked
Web API Binder Attribute For Property RRS feed

  • Question

  • User-1120466787 posted

    Dear folks,

    I'm creating a new project wholly from scratch, all by my self, and i'm such a incomplete person to now all the things...

    The project uses Mongo DB as database, and consume JSON/BSON models all around, There are lot of issues that i'm facing currently, but one thing i need to be fixed so quickly is that the project should be able to receive user data...

    My model is complex and i do not wish to create any DTO/VM/etc... as it can get complicated and out of hand, so i stick to my database model hopefully as far as i can get...

    The model structure is the inheritence based one, which i have a model of data, which another object complete it in someway and another one complete it in another way, and still these objects get inherited by something else... that's how this tree of models definition got big and yet far incomplete...

    The data i send from client to server are anotated by $type field which define class name and namespace, i do not remember if i filled the assembly name too or not... just as json default structure...

    then at server, i recieve this:

    public async Task<IHttpActionResult> Insert([ModelBinder(BinderType=typeof(JsonBodyModelBinder<BasePlace>))]BasePlace basePlace) { ... }

    wow great, everythings work fine, i also share the binder code later on at the end of the thread.

    But the issue is i need to send images too beside my model, and the only way i found out, was to upload images, then return my file names, after that pass the file name which was not compatible with my model, to the client, and add it to some list, then send the names beside my model, and after full confirmation, upload them to database for replication and horizontal scaling matters (not sure if it was good openion or not), so i changed signature to:

    public async Task<IHttpActionResult> Insert([ModelBinder(BinderType=typeof(JsonBodyModelBinder<BasePlace>))]BasePlace basePlace, List<string> mapFiles, List<string> imageFiles){ ... }

    Hopping the web api like mvc will use the parameters name to do the binding, but my thought failed...

    So i used:

    public async Task<IHttpActionResult> Insert([ModelBinder(BinderType=typeof(JsonBodyModelBinder<NestInputModel>))]NestInputModel inputModel){ ... }
    
    // MY WEB API MODEL
        public class NestInputModel
        {
            public BasePlace BasePlace { get; set; } //TODO: BIND TO SUB MODELS
            public List<string> MapFiles { get; set; }
            public List<string> ImageFiles { get; set; }
        }

    And that was the time i noticed that the binder failes at such time were model is not directly in touch...

    I tried to search and figure a way out, but the people code and even mine are complicated, i hardly get it, and what i saw till now: 1. they use same binding as me, 2. they put default binder which seem complex to me, on the exact class, but my entity model is in different project, and i wish not to touch it due later cause...

    So, for the first problem, please help me to solve this issue, to bind my data to the server WebAPI2, where inheritence is matter, and the inherited model is a property or generic property of the given class.

    Thank you,

    Hassan Faghihi.

    The Binder Code that i promised:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.Web;
    
    namespace RealEstate.Binders
    {
        public class TypeNameSerializationBinder : SerializationBinder
        {
            public string TypeFormat { get; private set; }
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="typeFormat">{0}->assemblyName | {1}->typeName</param>
            public TypeNameSerializationBinder(string typeFormat)
            {
                TypeFormat = typeFormat;
            }
    
            public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
            {
                assemblyName = null;
                typeName = serializedType.Name;
            }
    
            public override Type BindToType(string assemblyName, string typeName)
            {
                string resolvedTypeName = string.Format(TypeFormat, assemblyName, typeName);
    
                return Type.GetType(resolvedTypeName, true);
            }
        }
    }
    
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Web;
    using System.Web.Http.Controllers;
    using System.Web.Http.ModelBinding;
    //Web HTTP? ....
    using Newtonsoft.Json;
    
    namespace RealEstate.Binders
    {
        
    
        public class JsonBodyModelBinder<T> : IModelBinder
        {
            public bool BindModel(HttpActionContext actionContext,
                ModelBindingContext bindingContext)
            {
                if (bindingContext.ModelType != typeof(T))
                {
                    return false;
                }
    
                try
                {
                    var json = ExtractRequestJson(actionContext);
    
                    bindingContext.Model = DeserializeObjectFromJson(json);
    
                    return true;
                }
                catch (JsonException exception)
                {
                    bindingContext.ModelState.AddModelError("JsonDeserializationException", exception);
    
                    return false;
                }
    
    
                return false;
            }
    
            private static T DeserializeObjectFromJson(string json)
            {
                var binder = new TypeNameSerializationBinder("{1}, {0}");
    
                var obj = JsonConvert.DeserializeObject<T>(json, new JsonSerializerSettings
                {
                    TypeNameHandling = TypeNameHandling.Auto,
                    Binder = binder
                });
                return obj;
            }
    
            private static string ExtractRequestJson(HttpActionContext actionContext)
            {
                var content = actionContext.Request.Content;
                string json = content.ReadAsStringAsync().Result;
                return json;
            }
        }
    }

    Monday, October 9, 2017 10:09 PM

All replies

  • User-271186128 posted

    Hi deadManN,

    upload them to database for replication and horizontal scaling matters (not sure if it was good openion or not), so i changed signature to:

    public async Task<IHttpActionResult> Insert([ModelBinder(BinderType=typeof(JsonBodyModelBinder<BasePlace>))]BasePlace basePlace, List<string> mapFiles, List<string> imageFiles){ ... }

    Hopping the web api like mvc will use the parameters name to do the binding, but my thought failed...

    What do you mean about "my thought failed"? The parameter is null? If that is the case, please check the client code and the http request, make sure the parameters are correct.

    So i used:

    public async Task<IHttpActionResult> Insert([ModelBinder(BinderType=typeof(JsonBodyModelBinder<NestInputModel>))]NestInputModel inputModel){ ... }
    
    // MY WEB API MODEL
        public class NestInputModel
        {
            public BasePlace BasePlace { get; set; } //TODO: BIND TO SUB MODELS
            public List<string> MapFiles { get; set; }
            public List<string> ImageFiles { get; set; }
        }

    And that was the time i noticed that the binder failes at such time were model is not directly in touch...

    As for this issue, I suppose perhaps it is related to the ModelBinder, it's not apply for the NestInputModel model.

    If possible, I suggest you could share your project using onedrive, so that we could test it on our side.

    Besides, if you want to upload file using Web API, I suggest you could refer to the following articles:

    https://www.codeproject.com/Articles/806075/File-Upload-using-jQuery-AJAX-in-ASP-NET-Web-API

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part-2

    http://www.c-sharpcorner.com/UploadFile/2b481f/uploading-a-file-in-Asp-Net-web-api/

    Best regards,
    Dillion

    Tuesday, October 10, 2017 9:47 AM
  • User-1120466787 posted

    1. In MVC, you can send several model, or a single super set of models, and then the MVC controller bind each model to representing name that it find within the data... but it didn't and throw internal server errors

    2. Yes it's model binder, but i'm not an advance user who knows everything, and i have troubles with many of system inner structure like this one.

    I have no offence against sharing my project, but to be defense at the state i am, i like it to happen in a private manner, it's at it's critical point, and since i have little time to spare, and also that i didn't upload any part of it, it can be a bad idea for me, not till it grow a little bit through public... So how can we do proceed? should i contact you via email?

    thanks for the articles, i will look at them later on, when i'm not at work

    Tuesday, October 10, 2017 12:17 PM
  • User-271186128 posted

    Hi deadManN,

    I found that you have share your project using one drive via email, but unfortunately, I can't extract files from the ZIP file. The screenshot as below:

    So, could you share your project again?

    If the Model Binder still not working, I suggest you could try to use Model Binder to get the BasePlace, and refer to the articles in my previous to get the upload images.

    If you don't want share the whole project on this forum, I suggest you could post the client code or the http request, it might be easier for us to help you.

    Best regards,
    Dillion

    Tuesday, October 24, 2017 8:28 AM
  • User-1120466787 posted

    everyday i looked at message box, and didn't think you may response here :D

    Sorry for that, i put a '1' password, so an issue won't come up, for example i exprienced sending file through GMail, and it blocks content with .cs extensions, so just to make sure i made a '1' password on it, seem i forgot to say it

    Friday, October 27, 2017 2:29 AM
  • User-1120466787 posted

    I'm not sure what happened, but i got new error, so i moved to next stage, looking at people answer i found that the error is related to contractResolver, it should ignore a non used property so i done some search found a thread, but it doesn't work for my case...

    https://stackoverflow.com/questions/13588022/exclude-property-from-serialization-via-custom-attribute-json-net

    i went with drzaus asnwer, and then add Steve Rukuts answer to it, had no luck... maybe because my model is nested, or because i use custom type handling class, or maybe it can't cast null to datetime, because they didn't fill it with default value instead or many other thing, i can't understand ...

    i tried to register for all these conditions:

    var result = new IgnorableSerializerContractResolver(); 
    //result.Ignore(typeof(BasePlace), "CreationTime"); 
    result.Ignore<BasePlace>(w => w.CreationTime); 
    result.Ignore(typeof(BasePlace), "creationTime");/*??? small??*/ 
    result.Ignore(typeof(BasePlace), "basePlace.creationTime"); 
    return result;

    but none worked, my base model is as:

    namespace RealEstate.Api
    {
        public class NestInputModel
        {
            public BasePlace BasePlace { get; set; }
            public List<string> MapFiles { get; set; }
            public List<string> ImageFiles { get; set; }
        }
    }

    and the nested one:

        [BsonDiscriminator("BasePlace", RootClass = true)]
        [BsonKnownTypes(typeof(RealProperty))]
    
        public class BasePlace
        {
            [BsonRepresentation(BsonType.ObjectId)]
            public string Id { get; set; }
            //The Code Stored In RealInstitute Documents
            [BsonElement("Code")]
            public string Code { get; set; }
            public DateTime CreationTime { get; set; }
            public DateTime UpdateTime { get; set; }
            [BsonElement("AddressInfo")]
            public AddressInfo AddressInfo { get; set; }
        }

    and i get this error:

    {"Error converting value {null} to type 'System.DateTime'. Path 'basePlace.creationTime', line 1, position 112."}

    my incoming model is something like:

    {
    	"basePlace": {
    		"$type": "RealEstate.Entity.Models.Land, RealEstate.Entity",
    		"id": null,
    		"code": "fgdf",
    		"creationTime": "",
    		"updateTime": "",
    		"addressInfo": {
    			"country": {
    				"id": "59c527c0ce81172440102650",
    				"name": "Iran",
    				"languageBasedNames": [{
    						"name": "Iran",
    						"language": {
    							"id": "59c5270cce8117244010264e",
    							"iso": "en",
    							"name": "English"
    						},
    						"aliases": ["Persia"]
    					}, {
    						"name": "ایران",
    						"language": {
    							"id": "59c52717ce8117244010264f",
    							"iso": "fa",
    							"name": "Persian"
    						},
    						"aliases": ["پرشیا"]
    					}
    				]
    			},
    			"stateOrProvince": {
    				"id": "59c52882ce81172440102653",
    				"name": "Tehran",
    				"type": 2,
    				"countryId": "59c527c0ce81172440102650",
    				"languageBasedNames": [{
    						"name": "تهران",
    						"language": {
    							"id": "59c52717ce8117244010264f",
    							"iso": "fa",
    							"name": "Persian"
    						},
    						"aliases": ["طهران"]
    					}
    				]
    			},
    			"city": {
    				"id": "59c528aece81172440102654",
    				"name": "Tehran",
    				"stateOrProvinceId": "59c52882ce81172440102653",
    				"countryId": "59c527c0ce81172440102650",
    				"languageBasedNames": [{
    						"name": "تهران",
    						"language": {
    							"id": "59c52717ce8117244010264f",
    							"iso": "fa",
    							"name": "Persian"
    						},
    						"aliases": ["طهران"]
    					}
    				]
    			},
    			"region": {
    				"id": null,
    				"name": "---",
    				"stateOrProvinceId": null,
    				"countryId": null,
    				"languageBasedNames": []
    			},
    			"address": "dasd",
    			"location": {
    				"longitude": 3,
    				"latitude": 2
    			}
    		},
    		"landSize": 6,
    		"dimension": {
    			"width": 5,
    			"length": 6
    		},
    		"description": "ds",
    		"maps": [],
    		"images": [],
    		"mainPlaque": "da",
    		"subPlaque": "wqe",
    		"phase": "ew",
    		"licence": "true",
    		"ditch": "true",
    		"hasCommercial": "true",
    		"mayoraltyAgreement": "true",
    		"document": "eqw",
    		"shareOfSixPart": 3,
    		"frontage": 4,
    		"frontageStreet": 4,
    		"frontageAllay": 4,
    		"exchange": "true",
    		"exchangeDescription": "312",
    		"price": 3
    	},
    	"mapFiles": [],
    	"imageFiles": []
    }
    

    and here's are binders:

    public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
    
                //Is It Required? Config "BasePlaceHttpParameterBinding"
                //config.ParameterBindingRules.Insert(0, descriptor => typeof(BasePlace).IsAssignableFrom(descriptor.ParameterType) ? new BasePlaceHttpParameterBinding(descriptor) : null);
    
    
    
                //Configure Web API so it will apply authorize attribute on all API Controllers by default
                config.Filters.Add(new AuthorizeAttribute());
    
                // Web API configuration and services
                // Configure Web API to use only bearer token authentication.
                config.SuppressDefaultHostAuthentication();
                config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
    
                // Use camel case for JSON data.
                config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    
                // Web API routes
                config.MapHttpAttributeRoutes();
    
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
    
                config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto;
                /////////////////////////////
                //config.Services.Insert(typeof(ModelBinderProvider), 0,
                //    new SimpleModelBinderProvider(typeof(BasePlace), new JsonBodyModelBinder<BasePlace>()));
    
                //config.Filters.Add(new Filters.WebApi.TimeoutExceptionHandler());
            }
        }
    
    
    
    
    [HttpPost]
            //public async Task<IHttpActionResult> Insert([ModelBinder(BinderType=typeof(JsonBodyModelBinder<BasePlace>))]BasePlace basePlace, List<string> mapFiles, List<string> imageFiles)
            //public async Task<IHttpActionResult> Insert([ModelBinder(BinderType=typeof(JsonBodyModelBinder<NestInputModel>))]NestInputModel inputModel)
            public async Task<IHttpActionResult> Insert([ModelBinder(BinderType = typeof(LimitedBasePlaceJsonBodyModelBinder<NestInputModel>))]NestInputModel inputModel)
            {
                ....
            }
    
        public class LimitedBasePlaceJsonBodyModelBinder<T> : JsonBodyModelBinder<T>
        {
            private readonly IContractResolver _contractResolver;
    
            public static IContractResolver ContractResolverFactory()
            {
                var result = new IgnorableSerializerContractResolver();
                //result.Ignore(typeof(BasePlace), "CreationTime"); ??? small??
                result.Ignore<BasePlace>(w => w.CreationTime);
                result.Ignore(typeof(BasePlace), "creationTime");// ??? small??
                result.Ignore(typeof(BasePlace), "basePlace.creationTime");
                return result;
            }
    
            public LimitedBasePlaceJsonBodyModelBinder():base(ContractResolverFactory())
            {
            }
        }
    
        public class JsonBodyModelBinder<T> : IModelBinder
        {
            private readonly IContractResolver _contractResolver;
    
            public JsonBodyModelBinder()
            {
                _contractResolver = new DefaultContractResolver();
            }
    
            public JsonBodyModelBinder(IContractResolver contractResolver)
            {
                if(contractResolver==null)
                    throw new ArgumentNullException(nameof(contractResolver), "contractResolver parameter is null");
    
                _contractResolver = contractResolver;
            }
    
            public bool BindModel(HttpActionContext actionContext,
                ModelBindingContext bindingContext)
            {
                if (bindingContext.ModelType != typeof(T))
                {
                    return false;
                }
    
                try
                {
                    var json = ExtractRequestJson(actionContext);
    
                    bindingContext.Model = DeserializeObjectFromJson(json, _contractResolver);
    
                    return true;
                }
                catch (JsonException exception)
                {
                    bindingContext.ModelState.AddModelError("JsonDeserializationException", exception);
    
                    return false;
                }
    
    
                return false;
            }
    
            private static T DeserializeObjectFromJson(string json, IContractResolver contractResolver)
            {
                var binder = new TypeNameSerializationBinder("{1}, {0}");
    
                var obj = JsonConvert.DeserializeObject<T>(json, new JsonSerializerSettings
                {
                    TypeNameHandling = TypeNameHandling.Auto,
                    Binder = binder,
                    ContractResolver = contractResolver
                    
                });
                return obj;
            }
    
            private static string ExtractRequestJson(HttpActionContext actionContext)
            {
                var content = actionContext.Request.Content;
                string json = content.ReadAsStringAsync().Result;
                return json;
            }
        }
    
        public class TypeNameSerializationBinder : SerializationBinder
        {
            public string TypeFormat { get; private set; }
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="typeFormat">{0}->assemblyName | {1}->typeName</param>
            public TypeNameSerializationBinder(string typeFormat)
            {
                TypeFormat = typeFormat;
            }
    
            public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
            {
                assemblyName = null;
                typeName = serializedType.Name;
            }
    
            public override Type BindToType(string assemblyName, string typeName)
            {
                string resolvedTypeName = string.Format(TypeFormat, assemblyName, typeName);
    
                return Type.GetType(resolvedTypeName, true);
            }
        }

     

    Tuesday, October 31, 2017 5:18 PM
  • User-271186128 posted

    Hi deadManN,

    deadManN

    {"Error converting value {null} to type 'System.DateTime'. Path 'basePlace.creationTime', line 1, position 112."}

    According to the error message, it seems the issue is related to the 'basePlace.creationTime' property, it is null. If you want to allow nulls, you could use nullable types, like this:

    public DateTime? CreationTime { get; set; }
    public DateTime? UpdateTime { get; set; }
    

    Otherwise, you could check whether the datetime is null, and set the default time.

    Best regards,
    Dillion

    Wednesday, November 1, 2017 2:55 AM
  • User-1120466787 posted

    As i said before the model is in different project, instead i like to tell it, only for this property, which i ignored, use default(XType) instead of (XType)null, or just null...

    also today morning when i woke up i just think (i'm not home to test it) that it returned BasePlace, but shouldn't it be my child model? or it get converted later?

    Wednesday, November 1, 2017 6:06 AM
  • User1324658857 posted

    If you can't modify the model in different project, you need to set the default value on your side before validate and send it to remote project.

    Thursday, November 2, 2017 9:53 AM
  • User-1120466787 posted

    so i can't tell the JSON Parser, hey use default(T) instead of (T)null, so once you ignore this object, you won't cast null to that value afterward?

    Friday, November 3, 2017 8:07 AM
  • User1324658857 posted

    As I said in my previous reply, you could check whether the data is null before validate or deserialize the object. Like this:

        public class ValidationActionFilter : ActionFilterAttribute
        {
            public override void OnActionExecuting(HttpActionContext actionContext)
            {
    //check whether the date is null if(actionContext.ModelState ==null)
    //set default date.
    //then validate the model. if (!modelState.IsValid) actionContext.Response = actionContext.Request .CreateErrorResponse(HttpStatusCode.BadRequest, modelState); } }

    in your code, before deserialize the object, you could check whether the date is null.

                    //check whether the date is null
    
                    //set the default date.
                    var json = ExtractRequestJson(actionContext);
    
                    //deserialize object
                    bindingContext.Model = DeserializeObjectFromJson(json);


     

    Monday, November 6, 2017 9:08 AM
  • User750338025 posted

    I would also need something like that for http://bettingcasinoslots.com/casino-review/slotty-vegas/. Did you manage to get it right?

    Tuesday, November 7, 2017 7:08 PM
  • User-1120466787 posted

    i hardly understand the context stuff... But one thing, how can i know if the object is null before extract the json?

    I mean even the platform doesn't know the type of my object, and only it's base type, how it can cast it? (i kow the create is part of base time, i ask it wholy). i got something to do, i try to test this right away after that issue. and see if i can do that, but i do not promise to know what is happening out there, and fix it.

    Wednesday, November 8, 2017 4:01 PM
  • User-1120466787 posted

    As I said in my previous reply, you could check whether the data is null before validate or deserialize the object. Like this:

        public class ValidationActionFilter : ActionFilterAttribute
        {
            public override void OnActionExecuting(HttpActionContext actionContext)
            {
                //check whether the date is null
                if(actionContext.ModelState ==null)
                //set default date.
    
                //then validate the model.
                if (!modelState.IsValid)
                    actionContext.Response = actionContext.Request
                         .CreateErrorResponse(HttpStatusCode.BadRequest, modelState);
            }
        }

    in your code, before deserialize the object, you could check whether the date is null.

                    //check whether the date is null
    
                    //set the default date.
                    var json = ExtractRequestJson(actionContext);
    
                    //deserialize object
                    bindingContext.Model = DeserializeObjectFromJson(json);

    Sorry for being late, it was more of work than i tought and i used sometime too rest/relax too.

    i tried what you said, found the section... but i had no luck:

    i made the method virtual and tried to fill the object with value, but i failed:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Http.Controllers;
    using System.Web.Http.ModelBinding; //Web HTTP? ....
    using Newtonsoft.Json;
    using Newtonsoft.Json.Serialization;
    using RealEstate.Api;
    using RealEstate.Entity.Models;
    
    namespace RealEstate.Binders
    {
        public class LimitedBasePlaceJsonBodyModelBinder<T> : JsonBodyModelBinder<T>
        {
            private readonly IContractResolver _contractResolver;
    
            public static IContractResolver ContractResolverFactory()
            {
                var result = new IgnorableSerializerContractResolver();
                //result.Ignore(typeof(BasePlace), "CreationTime"); ??? small??
                result.Ignore<BasePlace>(w => w.CreationTime);
                result.Ignore(typeof(BasePlace), "creationTime");// ??? small??
                result.Ignore(typeof(BasePlace), "basePlace.creationTime");
                return result;
            }
    
            public LimitedBasePlaceJsonBodyModelBinder():base(ContractResolverFactory())
            {
            }
    
            public override bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
            {
                if (bindingContext.Model is NestInputModel)
                {
                    ((NestInputModel) bindingContext.Model).BasePlace.CreationTime = default(DateTime);
                }else if (bindingContext.Model is BasePlace)
                {
                    ((BasePlace)bindingContext.Model).CreationTime = default(DateTime);
                }
    
                return base.BindModel(actionContext, bindingContext);
            }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Http.Controllers;
    using System.Web.Http.ModelBinding; //Web HTTP? ....
    using Newtonsoft.Json;
    using Newtonsoft.Json.Serialization;
    using RealEstate.Entity.Models;
    
    namespace RealEstate.Binders
    {
        public class JsonBodyModelBinder<T> : IModelBinder
        {
            private readonly IContractResolver _contractResolver;
    
            public JsonBodyModelBinder()
            {
                _contractResolver = new DefaultContractResolver();
            }
    
            public JsonBodyModelBinder(IContractResolver contractResolver)
            {
                if(contractResolver==null)
                    throw new ArgumentNullException(nameof(contractResolver), "contractResolver parameter is null");
    
                _contractResolver = contractResolver;
            }
    
            public virtual bool BindModel(HttpActionContext actionContext,
                ModelBindingContext bindingContext)
            {
                if (bindingContext.ModelType != typeof(T))
                {
                    return false;
                }
    
                try
                {
                    var json = ExtractRequestJson(actionContext);
    
                    bindingContext.Model = DeserializeObjectFromJson(json, _contractResolver);
    
                    return true;
                }
                catch (JsonException exception)
                {
                    bindingContext.ModelState.AddModelError("JsonDeserializationException", exception);
    
                    return false;
                }
    
    
                return false;
            }
    
            private static T DeserializeObjectFromJson(string json, IContractResolver contractResolver)
            {
                var binder = new TypeNameSerializationBinder("{1}, {0}");
    
                var obj = JsonConvert.DeserializeObject<T>(json, new JsonSerializerSettings
                {
                    TypeNameHandling = TypeNameHandling.Auto,
                    Binder = binder,
                    ContractResolver = contractResolver
                    
                });
                return obj;
            }
    
            private static string ExtractRequestJson(HttpActionContext actionContext)
            {
                var content = actionContext.Request.Content;
                string json = content.ReadAsStringAsync().Result;
                return json;
            }
        }
    }

    As you can see, when i try to fill the property of model, actually the model has no value so i can make it's property fill, because it's null...  so if even something gonna happen,  it requires me to do it within the json, which require json parsing and rewriting knowledge which i do not have

    Friday, November 10, 2017 10:31 AM