I am trying to download files from my controller. I am receiving a variable from from a different class and need to download what is on that variable. I know I am probably doing a lot wrong right now. Any guidance would help a lot
Here is my class and I am returning the value allPaths
public class DBQueries
{
public List<string> GetSpecificYears(string[] response)
{
List<string> allPaths = new List<string>();
if (response != null)
{
using (var db = new ....())
{
foreach (var aYear in response)
{
// access a DbSet from DbContext here!
List<string> paths = db.ClientStatement_Inventory
.Where(x => x.statementYear == aYear)
.Select(y => y.statementPath).ToList();
allPaths.AddRange(paths);
}
}
}
return allPaths;
}
}
}
I am then passing allPaths variable to my controller by setting var allYears = getyears.GetSpecificYears()
Here is my Controller:
public ActionResult ExportFile(string[] years, string[] months, string[]radio, string[] acctNum)
{
ClientStatement_Inventory theStatementPath = new ClientStatement_Inventory();
var thePath = theStatementPath.statementPath;
DBQueries getyears = new DBQueries();
var allYears = getyears.GetSpecificYears(years);
var document = new ClientStatement_Inventory();
var cd = new System.Net.Mime.ContentDisposition
{
FileName = document.statementYear,
Inline = false,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(document.statementPath, document.statementYear);
How can I download these files using the allyears variable that is holding all the info?
Related
I am doing an Asp.Net Core MVC6 App.
I am using TempData to use it from the View
I am using like this.
private async void CreateClaimsByUserRole(string role, string usertType)
{
List<string> permission = await _iUIConfig.CreateClaimsByUserRole(role, usertType);
TempData["MyList"] = permission;
TempData.Keep();
}
I am saving a List<string>
Here is some other functions
public async Task<List<string>> CreateClaimsByUserRole(string role, string usertType)
{
List<RolesAccessModel>? oResponse = await GetRolesPerApplication();
List<string> permissions = TransformRowsIntoPermissions(oResponse,role, usertType);
return permissions;
}
And
private List<string> TransformRowsIntoPermissions(List<RolesAccessModel>? rows, string role, string usertType)
{
List<string> permissionList = new();
if(rows!=null)
{
foreach (RolesAccessModel row in rows)
{
if (row.Roles!=string.Empty && row.Roles != null && !row.Roles.Contains(role))
continue;
if (row.UserType != string.Empty && row.UserType != null && !row.UserType.Contains(usertType))
continue;
// if we hget here we have a match
if (!permissionList.Contains(row.EventName))
permissionList.Add(row.EventName);
}
}
return permissionList;
}
As it says here
I can do this in the same Method and works fine..
List<string> SomeList = TempData["MyList"] as List<string>;
But if I want to retrieve the data in another Method, It is null..
The only way to retrieve data is using
var SomeList = TempData["MyList"] ;
I need to retrieve the data from the View, I have the same problem
#if (TempData["Claims"] != null)
{
var claims = TempData["MyList"] as List<string>;
#foreach (string permission in claims)
{
<p>#permission</p>
}
}
Where var claims = TempData["MyList"] as List<string>; is null
Reading this page, I also add in Program.cs
builder.Services.Configure<CookieTempDataProviderOptions>(options => {
options.Cookie.IsEssential = true;
});
But still does not work.
What I am missing?
Thanks
It was related a serialize/deserialize issue,If you are not trying with simple types,I recomand you to serialize it before adding it to the dictionary
If you try as below :
List<decimal> strlist = new List<decimal> { 1, 2, 3 };
TempData["SomeList"] = strlist;
You would got an error:
It indicates your TempDataDictionary would be serialized before appended to cookie
For Complex types, you could try as below:
List<string> strlist = new List<string> { "q", "w", "e" };
var jsonstr= JsonSerializer.Serialize(strlist);
TempData["SomeList2"] = jsonstr;
deserialize:
var tempobj2 = TempData["SomeList2"];
var list = JsonSerializer.Deserialize<List<string>>(tempobj2 as string);
and You could cast the value to string[] indicates it was serialized/deserialized like below:
List<string> strlist = new List<string> { "q", "w", "e" };
var jsonStr= JsonSerializer.Serialize(strlist);
var obj = JsonSerializer.Deserialize<string[]>(jsonStr) as object;
I created code to load definitions from an external API. The code iterates through a list of words, looks up a definition for each and then I thought to use EF to insert these into my SQL Server database.
However if I run this twice it will load the same definitions the second time. Is there a way that I could make it so that EF does not add the row if it already exists?
public IHttpActionResult LoadDefinitions()
{
var words = db.Words
.AsNoTracking()
.ToList();
foreach (var word in words)
{
HttpResponse<string> response = Unirest.get("https://wordsapiv1.p.mashape.com/words/" + word)
.header("X-Mashape-Key", "xxxx")
.header("Accept", "application/json")
.asJson<string>();
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(response.Body);
var results = rootObject.results;
foreach (var result in results)
{
var definition = new WordDefinition()
{
WordId = word.WordId,
Definition = result.definition
};
db.WordDefinitions.Add(definition);
}
db.SaveChanges();
}
return Ok();
}
Also would appreciate if anyone has any suggestions as to how I could better implement this loading.
foreach (var result in results)
{
if(!(from d in db.WordDefinitions where d.Definition == result.definition select d).Any())
{
var definition = new WordDefinition()
{
WordId = word.WordId,
Definition = result.definition
};
db.WordDefinitions.Add(definition);
}
}
You can search for Definition value.
var wd = db.WordDefinition.FirstOrDefault(x => x.Definition == result.definition);
if(wd == null) {
var definition = new WordDefinition() {
WordId = word.WordId,
Definition = result.definition
};
db.WordDefinitions.Add(definition);
}
In this way you can get a WordDefinition that already have your value.
If you can also use WordId in the same way:
var wd = db.WordDefinition.FirstOrDefault(x => x.WordId == word.WordId);
I am trying to use NRefactory to modify an existing piece of C# code. I have tried to use the method described in this article. I'm getting an exception complaining about duplicate changes. Can someone point out what I am doing wrong, and maybe point me in the right direction?
I have the following section of code:
// contains the source code that needs to be modified
var text = "...";
// is the name of the file in which the target class exists
var fileName = "Foo";
// is the name of the target class
var className = "Foo.cs";
// FormattingOptions and TextEditorOptions are properties available to
// the class containing this code...
var parser = new CSharpParser();
var syntaxTree = parser.Parse(text, fileName);
syntaxTree.Freeze();
var document = new StringBuilderDocument();
document.Text = syntaxTree.ToString(FormattingOptions);
using (var documentScript = new DocumentScript(document, FormattingOptions, TextEditorOptions))
{
var typeDeclarations = syntaxTree.Descendants.OfType<TypeDeclaration>().Where(typeDeclaration => typeDeclaration.Name == className);
var templateProviderDeclaration = typeDeclarations.SingleOrDefault();
if (templateProviderDeclaration != null)
{
var constructorDeclarations = templateProviderDeclaration.Descendants.OfType<ConstructorDeclaration>();
foreach (var constructorDeclaration in constructorDeclarations)
{
var assignmentExpressions = constructorDeclaration.Descendants.OfType<AssignmentExpression>();
foreach (var assignmentExpression in assignmentExpressions)
{
var leftExpression = assignmentExpression.Left;
if (leftExpression != null && leftExpression.ToString(FormattingOptions) == "this.templates")
{
var rightExpression = assignmentExpression.Right;
foreach (var arrayInitializerExpression in rightExpression.Children.OfType<ArrayInitializerExpression>())
{
// uses AddTemplate(), which is an extension method
// which takes in an expression and modifies it, and
// returns an expression
var newExpression = ((ArrayInitializerExpression)arrayInitializerExpression).AddTemplate();
documentScript.Replace(arrayInitializerExpression, newExpression);
}
}
}
}
}
// text retrieved here is *clobbered*, by a few characters
text = documentScript.CurrentDocument.Text;
}
Other Code...
public static class ExtensionMethods
{
public static ArrayInitializerExpression AddTemplate(this ArrayInitializerExpression expression)
{
// TODO : will modify the AST for the target expression
return (ArrayInitializerExpression)expression.Clone();
}
}
Update:
I am trying to change a line like this:
this.templates = new Dictionary<string, ITemplate>
{
{ "Foo", new FooTemplate() }
};
to:
this.templates = new Dictionary<string, ITemplate>
{
{ "Foo", new FooTemplate() },
{ "Bar", new BarTemplate() }
};
For the purposes of this question, the exact specifics of the change I am trying to make aren't important though. I suspect that I have something not constructed quite correctly, but I cannot figure out if that's the issue.
So I have a controller that returns json to my views that I need to test. I have tried using reflection with a dynamic data type to access a sub property of a list but I keep getting something similar to 'unable to cast' errors. Basically I have a list within a list that I want to access and verify things about but I can't access it. Has anyone tested json returned from their controller before in MVC4 and have advice?
Code:
// arrange
var repositoryMock = new Mock<IEdwConsoleRepository>();
var date = -1;
var fromDate = DateTime.Today.AddDays(date);
EtlTableHistory[] tableHistories =
{
new EtlTableHistory
{
Table = new Table(),
RelatedStatus = new BatchStatus(),
BatchId = 1
}
};
EtlBatchHistory[] batchHistories = { new EtlBatchHistory
{
Status = new BatchStatus(),
TableHistories = tableHistories
} };
repositoryMock.Setup(repository => repository.GetBatchHistories(fromDate)).Returns((IEnumerable<EtlBatchHistory>)batchHistories);
var controller = new EdwController(new Mock<IEdwSecurityService>().Object, repositoryMock.Object);
// act
ActionResult result = controller.BatchHistories(1);
// assert
Assert.IsInstanceOfType(result, typeof(JsonResult), "Result type was incorrect");
var jsonResult = (JsonResult)result;
var resultData = (dynamic)jsonResult.Data;
var returnedHistories = resultData.GetType().GetProperty("batchHistories").GetValue(resultData, null);
var returnedTableHistoriesType = returnedHistories.GetType();
Assert.AreEqual(1, returnedTableHistoriesType.GetProperty("Count").GetValue(returnedHistories, null), "Wrong number of logs in result data");
Here's an example:
Controller:
[HttpPost]
public JsonResult AddNewImage(string buildingID, string desc)
{
ReturnArgs r = new ReturnArgs();
if (Request.Files.Count == 0)
{
r.Status = 102;
r.Message = "Oops! That image did not seem to make it!";
return Json(r);
}
if (!repo.BuildingExists(buildingID))
{
r.Status = 101;
r.Message = "Oops! That building can't be found!";
return Json(r);
}
SaveImages(buildingID, desc);
r.Status = 200;
r.Message = repo.GetBuildingByID(buildingID).images.Last().ImageID;
return Json(r);
}
public class ReturnArgs
{
public int Status { get; set; }
public string Message { get; set; }
}
Test:
[TestMethod]
public void AddNewImage_Returns_Error_On_No_File()
{
// Arrange
ExtendedBuilding bld = repo.GetBuildings()[0];
string ID = bld.Id;
var fakeContext = new Mock<HttpContextBase>();
var fakeRequest = new Mock<HttpRequestBase>();
fakeContext.Setup(cont => cont.Request).Returns(fakeRequest.Object);
fakeRequest.Setup(req => req.Files.Count).Returns(0);
BuildingController noFileController = new BuildingController(repo);
noFileController.ControllerContext = new ControllerContext(fakeContext.Object, new System.Web.Routing.RouteData(), noFileController);
// Act
var result = noFileController.AddNewImage(ID, "empty");
ReturnArgs data = (ReturnArgs)(result as JsonResult).Data;
// Assert
Assert.IsTrue(data.Status == 102);
}
In your example it looks to me that the problem is here:
var resultData = (dynamic)jsonResult.Data;
var returnedHistories = resultData.GetType().GetProperty("batchHistories").GetValue(resultData, null);
The resultData object would be the exact type of the object that you returned in your action. So if you did something like:
List<String> list = repo.GetList();
return Json(list);
Then your resultData would be of type:
List<String>
Try making sure that you are returning your Object using the Json(obj) function.
You can deserialize your Json into a dynamic object and then ask for the property you want
Example:
dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
var propertyValue = obj.MyProperty; //Ask for the right property
You can add Json serializer from Nuget Json.Net package.
I have very simple code which explains itself.
List<string> Files = new List<string>( Directory.EnumerateFiles(PathLocation));
However I now wish to make life complicated and I have a file object.
public class File
{
public int FileId { get; set; }
public string Filename { get; set; }
}
Is there an optimal way to populate the string property of the class, ie is there a better way than using a foreach loop or similar?
Sure:
List<File> Files = Directory.EnumerateFiles(PathLocation).Select(f=> new File { FileId = /*...*/, Filename = f }).ToList();
You can use LINQ Select to replace foreach loop:
List<File> files = Files.Select(s => new File() { FileId = id, Filename = s})
.ToList();
But needless to create new List to optimize your code:
List<File> files = Directory.EnumerateFiles(PathLocation)
.Select(s => new File() { FileId = id, Filename = s})
.ToList();
MSDN is here
You can map the contents of Files into a List<File>:
var files = Files.Select(f => new File { Filename = f })
.ToList();
The same using LINQ syntax:
var query = from f
in Files
select new File { Filename = f };
var files = query.ToList();
List<File> bigList;
var stringList = bigList.Select(f=>f.Filename);