I am new to MVC (coming from WebForm background). I have a main view which contains 2 tabs that need the same model for table view. However, I created a partial view containing table structure to display data records in the 2 tabs asynchronously. One tab gets its data from CSV while the other gets from SQL Server based on user's selection but having the same model.
I have the screenshot of the concept below: The box in red depicts the Partial View, it has 2 buttons, one to commit the table data into the database while the other is to add more records if needed;
Partial view in Parent View screenshot
My challenge is: I have a class method that needs to get a CSV file from FileUpload
value and binds data to the model on the partial view.
See my model structure below:
[Table("atm")]
public class ATM
{
public ATM()
{
this._EJTransactions = new HashSet<EJTransaction>();
this._CassetteSettings = new HashSet<CassetteSetting>();
this._EJFileDownloads = new HashSet<EJFileDownload>();
this._CamFileDownloads = new HashSet<ImageFileDownload>();
this._TransImages = new HashSet<TransImage>();
this._UserAtms = new HashSet<UserAtms>();
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int atmId { get; set; }
[ForeignKey("ATMVendor")]
public int vendorId { get; set; }
[ForeignKey("BankBranch")]
public int branchId { get; set; }
[MaxLength(50)]
[Index("ix_uniq_terminal", 1, IsUnique = true)]
[DisplayName("Terminal ID")]
public string terminalId { get; set; }
[MaxLength(30)]
[Index("ix_uniq_ip", 1, IsUnique = true)]
[DisplayName("IP")]
public string ip { get; set; }
[MaxLength(100)]
[Index("ix_uniq_title", 1, IsUnique = true)]
[DisplayName("Title")]
public string title { get; set; }
[DisplayName("EJ Enabled")]
public bool ejEnabled { get; set; }
[DisplayName("Image Enabled")]
public bool camEnabled { get; set; }
[DisplayName("IsActive")]
public bool isActive { get; set; }
public virtual ATMVendor ATMVendor { get; set; }
public virtual BankBranch BankBranch { get; set; }
public virtual ICollection<EJTransaction> _EJTransactions { get; set; }
public virtual ICollection<CassetteSetting> _CassetteSettings { get; set; }
public virtual ICollection<EJFileDownload> _EJFileDownloads { get; set; }
public virtual ICollection<ImageFileDownload> _CamFileDownloads { get; set; }
public virtual ICollection<TransImage> _TransImages { get; set; }
public virtual ICollection<UserAtms> _UserAtms { get; set; }
}
The partial view binds to this model.
public class CSVAtmLoader
{
public IEnumerable<ATM> Read(string csvfile)
{
List<ATM> atmlist = new List<ATM>();
TextReader csvReader = new StreamReader(csvfile);
var csv = new CsvReader(csvReader, false);
csv.Configuration.DetectColumnCountChanges = true;
csv.Configuration.RegisterClassMap<AtmMap>();
//csv.Configuration.InjectionCharacters = new[] { '=', '@', '+', '-' };
//csv.Configuration.SanitizeForInjection = false;
//csv.Configuration.InjectionEscapeCharacter = '\t';
var atms = csv.GetRecords<ATM>();
foreach (var atm in atms)
{
atm.branchId = GetBranchId(atm.BankBranch.branch);
atm.vendorId = GetVendorId(atm.ATMVendor.vendor);
atmlist.Add(atm);
}
return atmlist;
}
private int GetBranchId(string branch)
{
BankBranch br = new BankBranch { branch = branch }.SelectBranch();
return 0;
}
private int GetVendorId(string vendor)
{
return 0;
}
}
In the parent view, I have a CSVAtm tab that hosts the partial view, I am headway blocked to get this done with dynamism of the layout. See my parent view that render the partial view with csvfile chosen from FileUpload control:
<div class="tab-pane fade" id="csvAtm">
<p>
<div class="form-inline">
<table>
<tr>
<td><span> Choose a File:</span> </td>
<td><input id="csvfile" type="file" name="file" class="btn btn-default" onchange="clear();"/></td>
<td> </td>
<td>
<input class="btn btn-default col-mid-2" type="button" id="upload" value="Upload" onclick="uploadfile();" />
</td>
</tr>
</table>
</div>
<div id="error"></div>
<br />
<div class="form-group">
@{
if (string.IsNullOrEmpty(filename))
{
//this is where my challenge is, how to get the filename from fileupload
//I know this is executed at the server side and hence, the client is not aware of server side scripting
Html.RenderPartial("LoadedAtms", new CSVAtmLoader().Read(filename));
}
}
</div>
I need a better way to achieve this with fileupload security in mind, my approach might be wrong. If I can achieve this successfully in the csv tab, it will be easier to replicate same for connecting to Sql server.
Thanks so much..