I'm using ASP.NET-MVC and I'm having trouble with JSON strings.
This is the server side action:
[HttpPost]
public string Post([FromBody] GetIncidentsRequest value)
{
List<Incident> incidentList = ReadIncidentsFromTable(value.Status);
PagedList<Incident> pagedIncidentList = new PagedList<Incident>(incidentList, value.Page, value.PageSize);
string serialisedJSON = JsonConvert.SerializeObject(pagedIncidentList);
return serialisedJSON;
}
This is the client side action:
public ActionResult AppHistoricalIncidents(string sortOrder = "id", int page = 1, int pageSize = 1)
{
string serialisedJSON = JsonConvert.SerializeObject(new GetIncidentsRequest
{
SortOrder = sortOrder,
Page = page,
PageSize = pageSize,
Enumber = GetCurrentUserEnumber(),
Status = Incident.EnumStatus.Completed
});
string response = string.Empty;
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/json";
try
{
response = wc.UploadString(new Uri("http://localhost:25657/api/GetIncidents"), serialisedJSON);
}
catch (Exception ex)
{
Debug.Print(ex.ToString());
Console.WriteLine(ex.ToString());
}
PagedList<Incident> retVal = JsonConvert.DeserializeObject<PagedList<Incident>>(response);
return PartialView(retVal);
}
}
The content of the string serialisedJSON that gets returned is
[{"Type":0,"ID":2,"BusinessAreaID":3,"AppID":70,"SubProcess":71,"SubProcessName":"something something","SitesAffected":["Teesside"],"Example":"Doesnt work","Replication":"meh","initialComment":null,"RaiserContactNumber":"07703555555","RaiserContactEmail":"test@test.co.uk","RaisedBy":"E0000001","AssignedTo":"E0000002","RootCause":"lots lol","LastModifiedBy":null,"LastModifiedDate":"0001-01-01T00:00:00","CreationDate":"0001-01-01T00:00:00","TimeTakenByDev":0,"Status":1,"ShouldEmail":false,"AffectedWorkstations":["B0123123"],"Comments":[]}]
I get the error:
Could not cast or convert from System.String to PagedList.PagedList`1[Shared.Models.Incident].
It's like the Post action is returning a PagedList rather than a string, but that can't be right, what am I doing wrong here?
The error seems to come from the line:
response = wc.UploadString(new Uri("http://localhost:25657/api/GetIncidents"), serialisedJSON);
Full stack trace below:
[ArgumentException: Could not cast or convert from System.String to System.Collections.Generic.List`1[CIADashShared.Models.Incident].]
Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable(Object value, Type initialType, Type targetType) +225
Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast(Object initialValue, CultureInfo culture, Type targetType) +123
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType) +348
[JsonSerializationException: Error converting value "[{"Type":0,"ID":2,"BusinessAreaID":3,"AppID":70,"SubProcess":71,"SubProcessName":"something something","SitesAffected":["Teesside"],"Example":"Doesnt work","Replication":"meh","initialComment":null,"RaiserContactNumber":"07703555555","RaiserContactEmail":"test@test.co.uk","RaisedBy":"E000001","AssignedTo":"E0000002","RootCause":"lots lol","LastModifiedBy":null,"LastModifiedDate":"0001-01-01T00:00:00","CreationDate":"0001-01-01T00:00:00","TimeTakenByDev":0,"Status":1,"ShouldEmail":false,"AffectedWorkstations":["B0123123"],"Comments":[]}]" to type 'System.Collections.Generic.List`1[CIADashShared.Models.Incident]'. Path '', line 1, position 42538.]
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType) +420
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) +273
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) +453
Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) +209
Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings) +137
Newtonsoft.Json.JsonConvert.DeserializeObject(String value, JsonSerializerSettings settings) +66
CIA_Dash.Controllers.MaintenanceController.AppHistoricalIncidents(String sortOrder, Int32 page, Int32 pageSize) in C:\dev\CIA Dash\CIA Dash\Controllers\MaintenanceController.cs:364
lambda_method(Closure , ControllerBase , Object[] ) +192
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +14
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +157
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +22
System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +29
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +50
System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +228
System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +26
System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36
System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.Mvc.<>c__DisplayClassa.<EndProcessRequest>b__9() +22
System.Web.Mvc.<>c__DisplayClass4.<Wrap>b__3() +10
System.Web.Mvc.ServerExecuteHttpHandlerWrapper.Wrap(Func`1 func) +27
System.Web.Mvc.ServerExecuteHttpHandlerWrapper.Wrap(Action action) +64
System.Web.Mvc.ServerExecuteHttpHandlerAsyncWrapper.EndProcessRequest(IAsyncResult result) +71
System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride) +1436
[HttpException (0x80004005): Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.]
System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride) +3472700
System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage) +76
System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +29
System.Web.HttpServerUtilityWrapper.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +24
System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues, TextWriter textWriter) +461
System.Web.Mvc.Html.ChildActionExtensions.Action(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues) +83
System.Web.Mvc.Html.ChildActionExtensions.Action(HtmlHelper htmlHelper, String actionName, String controllerName) +11
ASP._Page_Views_Apps_Support_cshtml.Execute() in c:\dev\CIA Dash\CIA Dash\Views\Apps\Support.cshtml:66
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +197
System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +105
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +90
System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +235
System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +107
System.Web.Mvc.HtmlHelper.RenderPartialInternal(String partialViewName, ViewDataDictionary viewData, Object model, TextWriter writer, ViewEngineCollection viewEngineCollection) +277
System.Web.Mvc.Html.PartialExtensions.Partial(HtmlHelper htmlHelper, String partialViewName, Object model, ViewDataDictionary viewData) +91
System.Web.Mvc.Html.PartialExtensions.Partial(HtmlHelper htmlHelper, String partialViewName, Object model) +33
ASP._Page_Views_Apps_AppID_cshtml.Execute() in c:\dev\CIA Dash\CIA Dash\Views\Apps\AppID.cshtml:70
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +197
System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +105
System.Web.WebPages.StartPage.RunPage() +17
System.Web.WebPages.StartPage.ExecutePageHierarchy() +64
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +78
System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +235
System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +107
System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +291
System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +56
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +52
System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +173
System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36
System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9765901
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
OK I figured this out and fixed the issue by applying the following method to the response string prior to deserialization
private string FixApiResponseString(string input)
{
input = input.Replace("\\", string.Empty);
input = input.Trim('"');
return input;
}
The problem was that the string as returned by the API had \ escape characters before each occurrence of ", as well as enclosing the string in another set of unnecessary quotes. Stripping these out solved the problem
I would recommend you to return the list of entities from the web API end points instead of a string. PagedList is a class you are using for the paging in the razor view. Your Web API endpoint should return the data in JSON format, not string for the PagedList collection!. PagedList is more like something the MVC views use and you should not mix that in the web API endpoint. This allows another part of your code to consume the same endpoint (Imagine you are adding a SPA front end and your angular service can call this web API endpoint to get the data)
If your web API endpoint is returning a collection of Incident
objects, you can
simply call that endpoint, read the result as string and deserialize it to a list of Incident
entities again and then convert that to PagedList
I would also recommend using HttpClient
instead of WebClient
, which is the old way of making HTTP calls.
var httpClient = new HttpClient {BaseAddress = new Uri("yourSiteBasedAddress")};
var r=new GetIncidentsRequest ();
// Set the properties for r as needed
var result = await httpClient.PostAsJsonAsync("api/GetIncidents", r);
var response = await result.Content.ReadAsStringAsync();
var list = Newtonsoft.Json.JsonConvert.DeserializeObject<IEnumerable<Incident>>(response);
var t = list.ToPagedList(1, 3);
User contributions licensed under CC BY-SA 3.0