Cannot pass complex object to another Action method - c#

I'm trying to pass an object using TempData to another action method. Instead of redirecting to the action method, the controller gives me a white screen with the current action method in the URL. If I comment out the line where I pass the object to TempData, it redirects correctly. Is my object too complex to pass? Is there an alternative way of passing a complex object to another action methods?
Where I pass the object to TempData:
public async Task<IActionResult> UploadFile(IFormFile file)
{
if (file == null || file.Length == 0)
return Content("file not selected");
else
{
var path = Path.Combine(
Directory.GetCurrentDirectory(), "wwwroot",
"processes.json");
using (var stream = new FileStream(path, FileMode.Create))
{
await file.CopyToAsync(stream);
}
RetrieveModels rm = rm = new RetrieveModels(path);
List<FoundPattern> foundList = new List<FoundPattern>();
List<ProcessModel> processes = rm.Processes;
FindPatterns findp = new FindPatterns(processes, pt.KpiPatterns);
foundList = findp.fp;
TempData["list"] = foundList.ToList();
TempData["Name"] = "Multiple Business Processes";
return RedirectToAction("Overview");
}
}
Action method I want to get redirected to:
public IActionResult Overview()
{
var list = TempData["list"] as List<FoundPattern>;
ViewData["Name"] = TempData["Name"];
return View(list);
}
List of objects I'm trying to pass to TempData:
public class FoundPattern
{
public KpiPattern pattern = new KpiPattern();
public List<FoundElement> elements = new List<FoundElement>();
}
List of objects within object:
public class FoundElement
{
public List<string> ElementNames = new List<string>();
public bool Present { get; set; }
}
Response headers when it works:
HTTP/1.1 302 Found
Location: /Home/Overview
Server: Kestrel
Set-Cookie: .AspNetCore.Mvc.CookieTempDataProvider=CfDJ8Mu_qDgU_59HncGqqkEm39LG_cUi_rzUyuXXaEYreUFPL2etHRuHPv_5GVKDLcIIcvFhQg1KOzDBfhbvDbjZDpcp8JYzq5kpLHtfnw962pyXNHyCNbx_MOkKwGFSG_dQ_M7LlSVxWYHjqalsSe26K4IlRfGN8V9B5MAgIhWoURgF; path=/; samesite=strict; httponly
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcWkFUXHNvdXJjZVxyZXBvc1xLUEl0b29sXEtQSXRvb2xcSG9tZVxVcGxvYWRGaWxl?=
X-Powered-By: ASP.NET
Date: Wed, 07 Feb 2018 10:38:40 GMT
Content-Length: 0
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
Server: Kestrel
Set-Cookie: .AspNetCore.Mvc.CookieTempDataProvider=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; samesite=strict
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcWkFUXHNvdXJjZVxyZXBvc1xLUEl0b29sXEtQSXRvb2xcSG9tZVxPdmVydmlldw==?=
X-Powered-By: ASP.NET
Date: Wed, 07 Feb 2018 10:38:40 GMT
Response headers when it doesn't work:
HTTP/1.1 500 Internal Server Error
Server: Kestrel
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcWkFUXHNvdXJjZVxyZXBvc1xLUEl0b29sXEtQSXRvb2xcSG9tZVxVcGxvYWRGaWxl?=
X-Powered-By: ASP.NET
Date: Wed, 07 Feb 2018 10:41:28 GMT
Content-Length: 0

You are using the CookieTempDataProvider to manage TempData. Alas, it results in storing the TempData in cookies, as the name suggests.
The problem is that your data is too large to fit in the cookie. You may wish to use a different ITempDataProvider implementation (such as SessionStateTempDataProvider).

Related

Unable to show image on page returned by Web API

I need to show the image on my web page. I have given the url of the image as:
<img src="http://localhost:57401/assets/getimagebyid/?userId=22&imageId=2012" alt="Sample Image">
This is the API method to get the stream:
public HttpResponseMessage GetImageById(int userId, int imageId)
{
var objResponse = new HttpResponseMessage();
var ImageStream = ImageStorage.DownloadImageStream(userId, imageId);
var resourceByteArray = new byte[ImageStream .Length];
var dataStream = new MemoryStream(resourceByteArray);
objResponse.Content = new StreamContent(dataStream);
objResponse.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
objResponse.StatusCode = HttpStatusCode.OK;
return objResponse;
}
These are the response headers in the developer console:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 209855
Content-Type: image/jpeg
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcaW5ldHB1Ylx3d3dyb290XFBob3RvQnV0bGVyXFBob3RvQnV0bGVyLkFQSVxhc3NldHNcZ2V0YXNzZXRzYnlpZFw=?=
X-Powered-By: ASP.NET
Date: Tue, 24 May 2016 10:57:09 GMT
There is no error in the above code. Also, the status is 200(OK). Why the image is not showing on the web page? What am I missing?

Passing data between controllers ASP.net API

So I'm trying pass user data from one controller to another. I've been reading a lot about it here ---> http://www.dotnet-tricks.com/Tutorial/webapi/F2aL081113-Passing-multiple-complex-type-parameters-to-ASP.NET-Web-API.html and this guy seems to be doing exactly what I want to do, and he's using .PostAsJsonAsync to do it.
This is controller 1, which takes in user data and basically re-routes it to the other controller for authentication.
public ActionResult IDB(IDBUser i)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:64819");
HttpResponseMessage result = client.PostAsJsonAsync("/api/Participant/Authenticate", i).Result;
if (result.IsSuccessStatusCode)
{
return View();
}
else { // hits this breakpoint with 500 server error
return View("Index");
}
}
}
}
This seems to successfully make it to the other controller (below), as I'm getting a 500 error. However, I've got a breakpoint right at the beginning of the method, and it never seems to hit it.
[System.Web.Http.ActionName("Authenticate")]
[System.Web.Http.HttpPost]
public HttpResponseMessage Authenticate(IDBUser u)
{ //breakpoint it neve hits is on this line
bool Authenticate = false;
CredentialTester ct = new CredentialTester(u.password, u.username);
bool isAuthenticatedInt = ct.IntTest();
bool isAuthenticatedAcp = ct.AcpTest();
if (isAuthenticatedInt == true || isAuthenticatedAcp == true)
{
Authenticate = true;
return Request.CreateResponse(HttpStatusCode.OK, Authenticate);
}
else Authenticate = false;
return Request.CreateResponse(HttpStatusCode.NotAcceptable);
}
Any help is apprecitaed. Thanks everyone!
UPDATE
: I was able to look at the error and it is listed here:
{StatusCode: 500, ReasonPhrase: 'Internal Server Error', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:{ Pragma: no-cache X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcYTU4NDYxOVxEb2N1bWVudHNcYXAxMDk1MTQtcWEtYXVvdG1hdGlvblxXaVFhLlZhbC1JZFxNVkNcV2lRYS5WYWwtSWQuV2ViU2VydmljZVxXaVFhLlZhbC1JZC5XZWJTZXJ2aWNlXFdpUWEuVmFsLUlkLldlYlNlcnZpY2VcYXBpXFBhcnRpY2lwYW50XEF1dGhlbnRpY2F0ZQ==?= Access-Control-Allow-Origin: * Access-Control-Allow-Headers: Content-Type, Accept Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Cache-Control: no-cache Date: Thu, 12 May 2016 17:07:39 GMT Server: Microsoft-IIS/8.0 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Content-Length: 2307 Content-Type: application/json; charset=utf-8 Expires: -1}}
it looks like there's a problem with my Access- Control-Origin. I've put the appropriate adjustments in my web.config file (I've had a similar error before) but no luck.

C# HttpClient PostAsJsonAsync -> Error reading string

Hi I try to call an web api by server side with:
using (var client = new HttpClient())
{
using (var rsp = client.PostAsJsonAsync<Request>(url, model).Result)
{
if (!rsp.IsSuccessStatusCode)
{
// throw an appropriate exception
}
var result = rsp.Content.ReadAsAsync<string>().Result;
}
}
but I get error
Error reading string. Unexpected token: StartObject. Path '', line 1, position 1.
If I try to call same url from jQuery
$.post('http://localhost/api/Test')
the server return
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json
Expires: -1
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Sun, 25 Oct 2015 12:15:56 GMT
Content-Length: 104
{
"Header": {
"Token": "Response",
"Timestamp": "2015-10-25T14:15:56.0092197+02:00"
}
}
The "model" arrive on api controller but I can't get response from request.
ReadAsAsync<T> attempts to deserialize the response to type T. In this case, you're saying you want to deserialize JSON to a string, which doesn't really make sense. Either use a type matching the response (i.e. a custom data structure containing Header, Token, etc.) or use ReadAsStringAsync() if you really want to get a string.

MVC Action Filter in IIS 7.5+ modifying response

I have a MVC action filter that I use to validate my models that is giving me different responses on different versions of IIS. Here is the code for the action filter.
public class ValidateModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var viewData = filterContext.Controller.ViewData;
var modelStateErrors = filterContext.Controller.ViewData.ModelState.Keys.SelectMany(key => filterContext.Controller.ViewData.ModelState[key].Errors);
string errorMessage;
if (modelStateErrors.Count() > 0)
{
ModelError error = modelStateErrors.FirstOrDefault();
if (error.ErrorMessage.IsNotNullOrEmpty())
{
errorMessage = error.ErrorMessage;
}
else if (error.Exception != null)
{
errorMessage = error.Exception.Message;
}
else
{
errorMessage = Messages.UNKNOWN_VALIDATION_ERROR;
}
}
else
{
errorMessage = Messages.UNKNOWN_VALIDATION_ERROR;
}
if (!viewData.ModelState.IsValid)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
filterContext.Result = new ContentResult { Content = errorMessage, ContentType = "text/plain" };
}
else
{
var controller = filterContext.Controller as WMSControllerBase;
if (controller != null)
{
controller.DisplayWarningMessage(errorMessage);
}
foreach (var param in filterContext.ActionParameters)
{
if (param.Key.ToLower() == "model" || param.Value is ViewModelBase)
{
viewData.Model = param.Value;
break;
}
}
if (viewData.Model is ViewModelBase)
{
(viewData.Model as ViewModelBase).RebuildModel();
}
filterContext.Result = new ViewResult
{
ViewData = viewData
};
}
}
base.OnActionExecuting(filterContext);
}
}
On an IIS 7.0 server the action filter works as intended and will produce responses like the following for AJAX calls.
HTTP/1.1 400 Bad Request
Cache-Control: private
Content-Type: text/plain; charset=utf-8
Server: Microsoft-IIS/7.0
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 08 Oct 2013 21:40:36 GMT
Content-Length: 47
The error message I want the end user to see.
However running on IIS 7.5 or later I get responses like the following. Apparently IIS or MVC decides to replace my response body with "Bad Request" and sets the type to text/html. Wondering what is going here, why would it modify the response like this?
HTTP/1.1 400 Bad Request
Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 08 Oct 2013 21:50:02 GMT
Content-Length: 11
Bad Request

Can't rename folder in SharePoint 2013 using REST

I'm having trouble renaming a folder inside a document library using the REST api provided by SharePoint 2013. Here is the code I'm using below.
string digest = String.Empty;
using (var response = await connector.HttpClient.PostAsync("_api/contextinfo", null, token))
{
response.EnsureSuccessStatusCode();
var obj = await response.ReadObject("d");
digest = obj["GetContextWebInformation"].Value<string>("FormDigestValue");
}
using (var request = new HttpRequestMessage(HttpMethod.Post, String.Format("/_api/Web/GetFolderByServerRelativeUrl('{0}')", operation.Path.FullName)))
{
request.Headers.Add("X-HTTP-Method", "MERGE");
request.Headers.Add("IF-MATCH", "*");
request.Headers.Add("X-RequestDigest", digest);
//{ '__metadata': { 'type': 'SP.Folder' }, 'Name': 'New name' }
dynamic obj = new JObject();
obj.__metadata = new JObject();
obj.__metadata.type = "SP.Folder";
obj.Name = operation.DesiredName;
request.Content = new ODataJObjectContent(obj);
using (var response = await connector.HttpClient.SendAsync(request, token))
{
response.EnsureSuccessStatusCode();
await response.ReadText();
}
}
In Fiddler here is the request:
POST http://2013.blah.com/_api/Web/GetFolderByServerRelativeUrl('/Shared%20Documents/Test') HTTP/1.1
X-HTTP-Method: MERGE
IF-MATCH: *
X-RequestDigest: 0xA7C057B3AECE805B7313909570F64B8EACD7A677014B8EBE7F75CC5A7C081F87973D94E7CC22346964ECAB1FE3C6B326DA3B67DF7A646FE6F47E9B1E686C3985,11 Apr 2013 15:13:05 -0000
Accept: application/json; odata=verbose
Content-Type: application/json; odata=verbose
Host: 2013.skysync.com
Content-Length: 50
Expect: 100-continue
{"__metadata":{"type":"SP.Folder"},"Name":"Test2"}
And then the response:
HTTP/1.1 204 No Content
Cache-Control: private, max-age=0
Expires: Wed, 27 Mar 2013 15:13:15 GMT
Last-Modified: Thu, 11 Apr 2013 15:13:15 GMT
Server: Microsoft-IIS/8.0
X-SharePointHealthScore: 0
SPClientServiceRequestDuration: 15
X-AspNet-Version: 4.0.30319
SPRequestGuid: 53bd109c-43bb-2064-4a1b-82298b670ece
request-id: 53bd109c-43bb-2064-4a1b-82298b670ece
X-RequestDigest: 0x9CDB4F31CC5F3877C4383657C12BEC6CFF10FC28AB6A0BB2D9D38B4279187CBD1450359BDFF07F0E63FF550BFF96C46E0476FB895CDA104348AC066D86246BC6,11 Apr 2013 15:13:15 -0000
X-FRAME-OPTIONS: SAMEORIGIN
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 15.0.0.4420
X-Content-Type-Options: nosniff
X-MS-InvokeApp: 1; RequireReadOnly
Date: Thu, 11 Apr 2013 15:13:15 GMT
Everything looks good until I go back to SharePoint and the Test folder is still the same name. I'm following the guidelines from here and I've seen other very similar examples. I can rename it through the interface without any problem.
Thanks in advance for any help!
The following example demonstrates how to rename Folder via SharePoint 2013 REST service
Scenario: rename Archive folder to 2015 located in Documents
library
using (var client = new SPHttpClient(webUri, userName, password))
{
RenameFolder(client, webUri.ToString(),"Documents/Archive","2015");
}
where
private static void RenameFolder(SPHttpClient client, string webUrl,string folderUrl,string folderName)
{
var folderItemUrl = webUrl + "/_api/web/GetFolderByServerRelativeUrl('" + folderUrl + "')/ListItemAllFields";
var data = client.ExecuteJson(folderItemUrl);
var itemPayload = new {
__metadata = new { type = data["d"]["__metadata"]["type"] },
Title = folderName,
FileLeafRef = folderName,
};
var itemUrl = data["d"]["__metadata"]["uri"];
var headers = new Dictionary<string, string>();
headers["IF-MATCH"] = "*";
headers["X-HTTP-Method"] = "MERGE";
client.ExecuteJson((string)itemUrl, HttpMethod.Post, headers, itemPayload);
}
Note:
SPHttpClient class - inherits from HttpClient and provides some additional SharePoint specific functionaly such as getting
request digest
SPHttpClientHandler class - hides all the intricacies related to SharePoint Online authentication
Try to add list in your manifest file. It seems like a permissions problem, and when you have to "trust" an application then choose the list which you want to operate with.

Categories

Resources