How to migrate HttpWebRequest for Multipart file to HttpClient - httprequest

I am working on an ASP.Net Core 2.0 API and one of the services I need to create is to upload files to a 3rd party site via their API. The examples for their API uses HttpWebRequest and I need to migrate this to use HttpClient.
Below is the relevant portion of their example code for a file upload.
var url = "https://localhost:44636/api/uploads";
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
var credentialCache = new CredentialCache();
var username = "APIUser";
var password = "APIUserPassword";
credentialCache.Add(new Uri(url), "Basic", new NetworkCredential(username, password));
request.Credentials = credentialCache;
request.PreAuthenticate = true;
request.Accept = "application/json";
request.AllowWriteStreamBuffering = true;
var uploadFileRequest = new UploadFileRequest();
uploadFileRequest.environment = "DEV";
uploadFileRequest.filename = filename;
uploadFileRequest.multipartFile = File.ReadAllText(filepath + #"\" + filename, UTF8Encoding.UTF8);
var boundaryText = "--ACI-XFER";
var bodyText = new StringBuilder();
bodyText.Append("--" + boundaryText + "\r\n");
bodyText.Append("Content-Disposition: form-data; name=\"filename\"" + "\r\n\r\n");
bodyText.Append(uploadFileRequest.filename + "\r\n");
bodyText.Append("--" + boundaryText + "\r\n");
bodyText.Append("Content-Disposition: form-data; name=\"environment\"" + "\r\n\r\n");
bodyText.Append(uploadFileRequest.environment + "\r\n");
bodyText.Append("--" + boundaryText + "\r\n");
bodyText.Append("Content-Disposition: form-data; name=\"multipartFile\"; filename=\"" +
uploadFileRequest.filename + "\"" + "\r\n");
bodyText.Append("Content-Type: text/plain" + "\r\n\r\n");
bodyText.Append(uploadFileRequest.multipartFile + "\r\n");
bodyText.Append("--" + boundaryText + "--");
var bodyBytes = UTF8Encoding.UTF8.GetBytes(bodyText.ToString());
request.ContentType = "multipart/form-data; boundary=" + boundaryText;
request.ContentLength = bodyBytes.Length;
var requestStream = request.GetRequestStream();
requestStream.Write(bodyBytes, 0, bodyBytes.Length);
requestStream.Close();
using (var webResponse = (HttpWebResponse)request.GetResponse())
{
if (webResponse.StatusCode == HttpStatusCode.OK)
{
using (var responseReader = new StreamReader(webResponse.GetResponseStream()))
{
var responseText = responseReader.ReadToEnd();
if (logger.IsDebugEnabled)
{
logger.Debug("HttpWebResponse: \r\n" + responseText + "\r\n");
}
}
return true;
}
else
{
if (logger.IsErrorEnabled)
{
logger.Error("HttpWebResponse Error UploadProcessFile(), Server: " +
webResponse.Server + ", StatusCode: " + webResponse.StatusCode + ", StatusDescription: " +
webResponse.StatusDescription);
}
return false;
}
}
}
In ASP.NET Core 2.0 using the HttpClient, I have come up with this code, but when I try to upload the file, I get a 400 error stating "Please select a file to upload"
boundryText = "ACI-XFER"
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://localhost:44636");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
string relativeUrl = "api/uploads";
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, relativeUrl);
var byteArray = new UTF8Encoding().GetBytes("APIUser:APIUserPassword");
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
using (var content = new MultipartFormDataContent(boundryText))
{
content.Add(new StringContent(uploadFileRequestDto.FileName + "\r\n"), "filename");
content.Add(new StringContent(uploadFileRequestDto.PdxEnvironment + "\r\n"), "environment");
Encoding encNoBoM = new UTF8Encoding(false);
content.Add(new StringContent(uploadFileRequestDto.TextFile + "\"" + "\r\n", encNoBoM, "text/plain"), "multipartfile", uploadFileRequestDto.FileName);
request.Content = content;
response = await client.SendAsync(request);
}
}
if (response.IsSuccessStatusCode)
{
string jsonResult = response.Content.ReadAsStringAsync().Result;
uploadFileResponseDto = (uploadFileResponseDto)JsonConvert.DeserializeObject(jsonResult);
uploadFileResponseDto.Success = true;
uploadFileResponseDto.StatusCode = 200;
return uploadFileResponseDto;
}
_logger.LogError("File upload for Id [{ID}] failed. Reason: {ReasonPhrase}", uploadFileRequestDto.Id, response.ReasonPhrase);
uploadFileResponseDto.Success = false;
uploadFileResponseDto.Reason = string.Format($"Status Code: [{response.StatusCode}], Reason: [{response.ReasonPhrase}]");
uploadFileResponseDto.StatusCode = 500;
return uploadFileResponseDto;
Here is the request as it looks in Fiddler;
**Headers**
POST /api/uploads HTTP/1.1
Connection: Keep-Alive
Content-Type: multipart/form-data; boundary="--ACI-XFER"
Accept: application/json
Authorization: Basic XXXXXXXXXXXXXXXXXXXXXX
x-ms-request-root-id: 4f112b3-4c33c20cb1d76dec
x-ms-request-id: |4f112b3-4c33c20cb1d76dec.1.
Request-Id: |4f112b3-4c33c20cb1d76dec.1.1.
Content-Length: 325354
Host: localhost:44636
Content
----ACI-XFER
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=filename
test1upload.txt
----ACI-XFER
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=environment
DEV
----ACI-XFER
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=multipartfile; filename=test1upload.txt; filename*=utf-8''test1upload.txt
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
I feel that the problem is coming from how I am doing this line in my code, which sets up the text file content to upload;
content.Add(new StringContent(uploadFileRequestDto.TextFile + "\"" + "\r\n", encNoBoM, "text/plain"), "multipartfile", uploadFileRequestDto.FileName);
I had first tried it like this, without the added and slashes and carriage return line feed, but got the same error.
content.Add(new StringContent(uploadFileRequestDto.TextFile, encNoBoM, "text/plain"), "multipartfile", uploadFileRequestDto.FileName);
But I am having difficulty finding a good example of how to do this.
Any ideas?

Related

failed-network error when downloading excel file

I have a button that will open a new window using javascript window.open to download an excel file, but chrome always shows "Failed-Network error."
The same code is running in another action, and it works fine.
var stream = new MemoryStream();
using (var package = new ExcelPackage(stream))
{
var workSheet = package.Workbook.Worksheets.Add("Sheet1");
workSheet.Cells["G1:J1"].Merge = true;
workSheet.Cells["G1:J1"].Value = "Translations";
workSheet.Cells["A2"].Value = "Key Name";
workSheet.Cells["B2"].Value = "Key Description";
workSheet.Cells["C2"].Value = "Key Type";
workSheet.Cells["D2"].Value = "Applications";
workSheet.Cells["E2"].Value = "English Text";
workSheet.Cells["F2"].Value = "Status";
workSheet.Cells["G2"].Value = "Arabic";
workSheet.Cells["H2"].Value = "French";
workSheet.Cells["I2"].Value = "Portugese";
workSheet.Cells["J2"].Value = "Spanish";
for (int i = 0; i < result.Data.Count; i++)
{
var currentKey = result.Data[i];
workSheet.Cells[i + 3, 1].Value = currentKey.Name;
workSheet.Cells[i + 3, 2].Value = currentKey.Description;
workSheet.Cells[i + 3, 3].Value = currentKey.LabelName;
workSheet.Cells[i + 3, 4].Value = string.Join(',',
appBL.GetLocalizationKeyApplicationNames(currentKey.Id).Data);;
workSheet.Cells[i + 3, 5].Value =
currentKey.EnglishTranslation;
workSheet.Cells[i + 3, 6].Value = currentKey.Status;
var translations = currentKey.Translations;
workSheet.Cells[i + 3, 7].Value =
translations.FirstOrDefault(t => t.Language ==
LanguageEnum.Arabic).Value;
workSheet.Cells[i + 3, 8].Value =
translations.FirstOrDefault(t => t.Language ==
LanguageEnum.French).Value;
workSheet.Cells[i + 3, 9].Value =
translations.FirstOrDefault(t => t.Language ==
LanguageEnum.Portuguese).Value;
workSheet.Cells[i + 3, 10].Value =
translations.FirstOrDefault(t => t.Language ==
LanguageEnum.Spanish).Value;
}
package.Save();
}
Response.Headers.Add("Content-Disposition",
string.Format("attachment;filename={0}",
$"localization keys-{DateTime.Now.ToString("yyyyMMdd")}"
+ ".xlsx"));
Response.Headers.Add("Transfer-Encoding", "identity");
Response.ContentLength = stream.Length;
return File(stream, "application/vnd.openxmlformats-
officedocument.spreadsheetml.sheet",
$"localization keys-
{DateTime.Now.ToString("yyyyMMdd")}.xlsx");
here is the request and response headers for the call
Request Headers:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Host: localhost:44374
Pragma: no-cache
Referer: https://localhost:44374/
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Response Headers:
Content-Disposition: attachment; filename="localization keys-20210103.xlsx"; filename*=UTF-8''localization%20keys-20210103.xlsx
Content-Length: 2731
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Date: Sun, 03 Jan 2021 06:44:15 GMT
Server: Microsoft-IIS/10.0
Transfer-Encoding: identity
X-Powered-By: ASP.NET
Any thoughts?
Thank you.
I just ran into the same issue, the solution relies in the front-end on your javascript, I would love to help you more, and I am willing to edit my response with a sample that relates to your code, if you could post your javascript on your original question.
for now I can give you the link that help me resolve my issue, it is not straight forward and again I am willing to give you a better answer if you can provide your javascript code.
Problems downloading big file(max 15 mb) on google chrome
and my implementation looks like this:
function saveAsFile(filename, bytesBase64) {
var data = window.atob(bytesBase64);
var bytes = new Uint8Array(data.length);
for (var i = 0; i < data.length; i++) {
bytes[i] = data.charCodeAt(i);
}
var blob = new Blob([bytes.buffer], { type: "application/octet-stream" });
var url = URL.createObjectURL(blob);
var link = document.createElement('a');
link.download = filename;
link.href = url;
document.body.appendChild(link); // Needed for Firefox
link.click();
document.body.removeChild(link);
}
i found the solution, i needed to set the position of the stream to 0
stream.Position = 0;

CKEDITOR File Upload Bad Request 400 Error

I am using ckEditor with the file browser, filemanager plugin in it. What i am trying to achieve when i configure the CKeditor I am able to browse the file in a certain folder .. but when i try to upload the file through it I am getting an error of 400 Bad Request may be there is something which I need to do ?
Following is my code
[HttpPost]
CKEDITOR.replace('content_editor',{
customConfig: '/assets/back/dist/plugins/ckeditor/config.js',
"imageBrowser_listUrl" : "/webmaster/files/browser"
});
CKEDITOR.on('fileUploadRequest', function (evt) {
var fileLoader = evt.data.fileLoader,
formData = new FormData(),
xhr = fileLoader.xhr;
xhr.open( 'PUT', fileLoader.uploadUrl, true );
formData.append( 'upload', fileLoader.file, fileLoader.fileName );
fileLoader.xhr.send( formData );
// Prevented the default behavior.
evt.stop();
} );
Request Handler C# ASP.NET CORE 3.1
public async Task<IActionResult> UploadFromEditor([FromForm]IFormFile upload)
{
if (upload.Length <= 0) return null;
if (!upload.IsImage())
{
var NotImageMessage = "please choose a picture";
dynamic NotImage = JsonConvert.DeserializeObject("{ 'uploaded': 0, 'error': { 'message': \"" + NotImageMessage + "\"}}");
return Json(NotImage);
}
var fileName = Guid.NewGuid() + Path.GetExtension(upload.FileName).ToLower();
Image image = Image.FromStream(upload.OpenReadStream());
int width = image.Width;
int height = image.Height;
if ((width > 750) || (height > 500))
{
var DimensionErrorMessage = "Custom Message for error";
dynamic stuff = JsonConvert.DeserializeObject("{ 'uploaded': 0, 'error': { 'message': \"" + DimensionErrorMessage + "\"}}");
return Json(stuff);
}
if (upload.Length > 500 * 1024)
{
var LengthErrorMessage = "Custom Message for error";
dynamic stuff = JsonConvert.DeserializeObject("{ 'uploaded': 0, 'error': { 'message': \"" + LengthErrorMessage + "\"}}");
return Json(stuff);
}
var path = Path.Combine(
Directory.GetCurrentDirectory(), "wwwroot/uploads/images/conten_images",
fileName);
using (var stream = new FileStream(path, FileMode.Create))
{
upload.CopyTo(stream);
}
var url = $"{"/uploads/images/CKEditorImages/"}{fileName}";
var successMessage = "image is uploaded successfully";
dynamic success = await Task.Run(() => JsonConvert.DeserializeObject("{ 'uploaded': 1,'fileName': \"" + fileName + "\",'url': \"" + url + "\", 'error': { 'message': \"" + successMessage + "\"}}"));
return Json(success);
}
Extra Plugins code :
CKEDITOR.editorConfig = function( config ) {
config.filebrowserBrowseUrl = '/assets/back/dist/ckeditor/plugins/imagebrowser/browser/browser.html'
config.filebrowserUploadUrl = '/webmaster/files/UploadFromEditor';
config.extraPlugins = 'filetools';
config.extraPlugins = 'uploadimage';
config.extraPlugins = 'popup';
config.extraPlugins = 'imagebrowser';
config.filebrowserUploadMethod = 'xhr';
};
Please help me out here
here are the headers :
XHRPOSThttps://localhost:5001/webmaster/files/UploadFromEditor
[HTTP/2 400 Bad Request 73ms]
POST
https://localhost:5001/webmaster/files/UploadFromEditor
Status400
Bad Request
VersionHTTP/2
Transferred85.50 KB (0 B size)
content-length
0
date
Tue, 03 Nov 2020 09:13:50 GMT
server
Kestrel
X-Firefox-Spdy
h2
Accept
*/*
Accept-Encoding
gzip, deflate, br
Accept-Language
en-US,en;q=0.5
Connection
keep-alive
Content-Length
86268
Content-Type
multipart/form-data; boundary=---------------------------1063707225330149515660008029
Cookie
.AspNetCore.Session=CfDJ8ERqQf6e11lCnNAhOo0wjyavEQJqEJ7gsv1MXMI4QwPk9Px8mznruNuZcxnmuYGnGjs1GtOWQI4DVCXYKd%2FRbNNo62%2FtopzHy%2FxaW87rvNE13QikL84JT0m32Ie1LWSZR3AkxYAE5p4U7TEpN5FccezCSMDeUR9geLW3lSjFIJD4; .AspNetCore.Antiforgery.J7MIrShXchg=CfDJ8ERqQf6e11lCnNAhOo0wjyYadzIaShP7Nt-bl6orx5lTMtnVoGxw8noimjE32qvhp_f96p2Hx4_zK8hzdRIz12615ZdyisBTz6X9HPA39cgIvRTjmWmrWNcLlm4S2MvPAQrG9hofg1ANinWAOwKIyXc; ckCsrfToken=8qZ4KEfRjaBWRmI6coRoRbJrZd8DgYG18gAz86eN; .AspNetCore.Antiforgery.XfkU3LYWHPY=CfDJ8NfGIpF9PVtNgLP3wXt3ZoscmmPZ8ZskVSbYiI69p4lPZYB3mt9mFEqRuOV0Ajfi2f8NNbjcyEHtfta7RlEHTBhXdRfPonXD1sN2EIS2BvcjZCrN8sJXN4UMo_JlolirVt3VIcCTm-wGAtIzGq0150w
Host
localhost:5001
Origin
https://localhost:5001
Referer
https://localhost:5001/webmaster/News/Create
TE
Trailers
User-Agent
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0
X-Requested-With
XMLHttpRequest
Cookie “.AspNetCore.Antiforgery.XfkU3LYWHPY” will be soon treated as cross-site cookie against “https://localhost:5001/webmaster/files/UploadFromEditor” because the scheme does not match. UploadFromEditor
Source map error: Error: request failed with status 404
Resource URL: https://localhost:5001/assets/back/dist/bootstrap/js/bootstrap.min.js
Source Map URL: bootstrap.min.js.map
Based on the details about your test request, it seems that you configured and enabled antiforgery token validation. If JavaScript client not set/include the token in request, which would cause 400 Bad Request error.
To fix it, as I mentioned in comment, we can apply IgnoreAntiforgeryToken Attribute to action method UploadFromEditor to skip antiforgery token validation.
Or set the token in request header to make the request can pass antiforgery token validation.
https://learn.microsoft.com/en-us/aspnet/core/security/anti-request-forgery?view=aspnetcore-3.1#javascript

how to send Content-Disposition: form-data; name="name" in correct way when call post api from C# to avoid statuserror 500

public async Task<T> PostFrom<T>(string baseAddress, string url, string requestbody)
{
T obj = default(T);
//Create the Uri string
string request = baseAddress + url;
WriteLog(request + " : " + "start");
try
{
//Create the Uri
var urirequest = new Uri(request);
//define MultipartFormDataContent
var multipart = new MultipartFormDataContent();
//Add Content-Type
multipart.Headers.Remove("Content-Type");
multipart.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=" + financialAuth.Value.ContentType.boundary);
//Add AuthToken
multipart.Headers.Add("AuthToken", financialAuth.Value.AuthToken);
//start adding the Content-Disposition which i have 3 of them
//1st Content-Disposition form-data; name="SearchCriteria" "requestbody" is the json
if (!string.IsNullOrEmpty(requestbody))
{
var requestbodyContent = new StringContent(JsonConvert.SerializeObject(requestbody));
requestbodyContent.Headers.Add("Content-Disposition", "form-data; name=\"SearchCriteria\"");
multipart.Add(requestbodyContent, "SearchCriteria");
}
//2nd Content-Disposition form-data; name="Secret" "financialAuth.Value.Secret" is the string
var secretContent = new StringContent(financialAuth.Value.Secret);
secretContent.Headers.Add("Content-Disposition", "form-data; name=\"Secret\"");
multipart.Add(secretContent, "Secret");
//3rd Content-Disposition form-data; name="AppID" "financialAuth.Value.AppID" is the string
var appIdContent = new StringContent(financialAuth.Value.AppID);
appIdContent.Headers.Add("Content-Disposition", "form-data; name=\"AppID\"");
multipart.Add(appIdContent, "AppID");
//define the HttpRequestMessage of type post
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, urirequest);
//assign the multipart of httpRequestMessage.Content
httpRequestMessage.Content = multipart;
//assign the urirequest of httpClient.BaseAddress
client.BaseAddress = urirequest;
WriteLog("start url" + request);
/* Here when I call the post web api I'm getting below error:
{{StatusCode: 500, ReasonPhrase: 'Internal Server Error', Version: 1.1, Content: System.Net.Http.HttpConnection+HttpConnectionResponseContent,
Headers: {
Cache-Control: no-cache
Pragma: no-cache
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type,authtoken
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Date: Tue, 26 Feb 2019 14:59:51 GMT
Content-Type: application/json; charset=utf-8
Expires: -1
Content-Length: 36
}}
*/
HttpResponseMessage response = await client.SendAsync(httpRequestMessage).ConfigureAwait(false);
WriteLog("END url" + request);
if (response.IsSuccessStatusCode)
{
WriteLog(request + " : " + "Begin Result");
string result = await response.Content.ReadAsStringAsync();
obj = JsonConvert.DeserializeObject<T>(result);
WriteLog(request + " : " + "End Result");
}
}
catch (Exception ex)
{
WriteLog(request + " " + ex.Message);
}
return obj;
}
I just solved the error by commenting the below code:
// Add Content-Type
multipart.Headers.Remove("Content-Type");
multipart.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=" + financialAuth.Value.ContentType.boundary);
It seems the content type will be created automatically by MultipartFormDataContent.
Thanks for looking into my issue.

Flickering when updating the datacontext in background

I'm studying UWP by Windows 10 development for absolute beginners, and I meet some problems.
Reflash my ObservableCollection<> data will cause the screen to flash. How do I fix it?
The program details are in UWP beginner
//CS FILE CODE
public sealed partial class FinancialPage : Page
{
ObservableCollection<NewsItem> NewsItems;
public FinancialPage()
{
NewsItems = new ObservableCollection<NewsItem>();
this.InitializeComponent();
GetNewsItemManager.GetNewItemsByCategory(NewsItems, "Financial");
}
}
// XAML FILE CODE
<GridView ItemsSource="{x:Bind NewsItems}" Background="LightGray">
<GridView.ItemTemplate>
<DataTemplate x:DataType="data:NewsItem">
<local:NewsContentControl HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
//MODELS NEWSITEMS CLASS FILE
public static void GetNewItemsByCategory(ObservableCollection<NewsItem> NewsItems, string Category)
{
var allnewsitems = getNewsItems();
var filteredNewsItems = allnewsitems.Where(p => p.Category == Category && IsExist(NewsItems, p.Id)).ToList();
filteredNewsItems.ForEach(p => NewsItems.Add(p));
}
private static Boolean IsExist(ObservableCollection<NewsItem> NewsItems, int Id)
{
return NewsItems.ToList().TrueForAll(p => Id == p.Id);
}
private static List<NewsItem> getNewsItems()
{
var items = new List<NewsItem>();
items.Add(new NewsItem() { Id = 1, Category = "Financial", Headline = "Lorem Ipsum", Subhead = "doro sit amet", DateLine = "Nunc tristique nec", Image = "Assets/Financial1.png" });
items.Add(new NewsItem() { Id = 2, Category = "Financial", Headline = "Etiam ac felis viverra", Subhead = "vulputate nisl ac, aliquet nisi", DateLine = "tortor porttitor, eu fermentum ante congue", Image = "Assets/Financial2.png" });
items.Add(new NewsItem() { Id = 3, Category = "Financial", Headline = "Integer sed turpis erat", Subhead = "Sed quis hendrerit lorem, quis interdum dolor", DateLine = "in viverra metus facilisis sed", Image = "Assets/Financial3.png" });
items.Add(new NewsItem() { Id = 4, Category = "Financial", Headline = "Proin sem neque", Subhead = "aliquet quis ipsum tincidunt", DateLine = "Integer eleifend", Image = "Assets/Financial4.png" }); items.Add(new NewsItem() { Id = 5, Category = "Financial", Headline = "Mauris bibendum non leo vitae tempor", Subhead = "In nisl tortor, eleifend sed ipsum eget", DateLine = "Curabitur dictum augue vitae elementum ultrices", Image = "Assets/Financial5.png" });
items.Add(new NewsItem() { Id = 6, Category = "Food", Headline = "Lorem ipsum", Subhead = "dolor sit amet", DateLine = "Nunc tristique nec", Image = "Assets/Food1.png" });
items.Add(new NewsItem() { Id = 7, Category = "Food", Headline = "Etiam ac felis viverra", Subhead = "vulputate nisl ac, aliquet nisi", DateLine = "tortor porttitor, eu fermentum ante congue", Image = "Assets/Food2.png" });
items.Add(new NewsItem() { Id = 8, Category = "Food", Headline = "Integer sed turpis erat", Subhead = "Sed quis hendrerit lorem, quis interdum dolor", DateLine = "in viverra metus facilisis sed", Image = "Assets/Food3.png" });
items.Add(new NewsItem() { Id = 9, Category = "Food", Headline = "Proin sem neque", Subhead = "aliquet quis ipsum tincidunt", DateLine = "Integer eleifend", Image = "Assets/Food4.png" });
items.Add(new NewsItem() { Id = 10, Category = "Food", Headline = "Mauris bibendum non leo vitae tempor", Subhead = "In nisl tortor, eleifend sed ipsum eget", DateLine = "Curabitur dictum augue vitae elementum ultrices", Image = "Assets/Food5.png" });
return items;
}
Assuming
NewsItem.Clear();
filteredNewsItems.ForEach(p => NewsItem.Add(p));
should be
NewsItems.Clear();
filteredNewsItems.ForEach(p => NewsItems.Add(p));
I assume the "flash" you are seeing (can't be certain as you haven't provided a full repro) is due to what you're doing to show the updated list.
Yes, removing everything and then adding a new (mostly similar) list back can create what some people describe as a "flash".
A better approach would be to remove the items you don't want displayed any more and then add in any extra ones you do.
Something like this:
foreach (var newsItem in NewsItems.Reverse())
{
if (newsItem.Category != Category)
{
NewsItems.Remove(newsItem);
}
}
foreach (var fni in filteredNewsItems)
{
if (!NewsItems.Contains(fni))
{
NewsItems.Add(fni);
}
}
OK... I think I've found a solution for you.
Instead of updating the bindings in your user control with the lambda expression, try it this way:
public NewsContentControl()
{
this.InitializeComponent();
this.DataContextChanged += OnDataCtxChanged; //+= (s, e) => Bindings.Update();
}
private void OnDataCtxChanged(FrameworkElement sender, DataContextChangedEventArgs args)
{
System.Diagnostics.Debug.WriteLine("context 'changed'");
if(NewsItem != args.NewValue as NewsItem)
{
Bindings.Update();
}
}
This triggers the update only if the value is actually different. Additionally, you can use "Binding" instead of x:Bind.
None of this answers for me why the datacontext is changing... but this should get rid of your flicker.

How can I get html code from Webpage with login?

I want to get the HTML Code from a Webpage (German Prepaid Provider).
I tried it with Webrequest but this does not work.
async private void connectToLidlConnect()
{
string user = UserName;
string pass = Password;
ASCIIEncoding encoding = new ASCIIEncoding();
string postData = "login=" + user + "&mdp=" + pass;
byte[] data = encoding.GetBytes(postData);
WebRequest request = WebRequest.Create("https://kundenkonto.lidl-connect.de/login.html");
request.Method = "PUT";
request.ContentType = "application/x-www-form-urlencoded";
request.Headers["ContentLength"] = data.Length.ToString();
using (Stream stream = await request.GetRequestStreamAsync())
{
stream.Write(data, 0, data.Length);
}
using (WebResponse response = await request.GetResponseAsync())
{
using (Stream stream = response.GetResponseStream())
{
using (StreamReader sr = new StreamReader(stream))
{
//
var a = sr.ReadToEnd();
}
}
}
}
How can I navigate to the next page with Cookies?
I Tried this too:
async public Task LogIn()
{
CookieContainer container;
var request = (HttpWebRequest)WebRequest.Create(LoginPageAdress);
request.Method = "PUT";
request.ContentType = "application/x-www-form-urlencoded";
var buffer = Encoding.ASCII.GetBytes(loginData.ToString());
request.Headers["ContentLength"] = buffer.Length.ToString();
var requestStream = await request.GetRequestStreamAsync();
requestStream.Write(buffer, 0, buffer.Length);
container = request.CookieContainer = new CookieContainer();
var request1 = (HttpWebRequest)WebRequest.Create(new Uri("https://kundenkonto.lidl-connect.de/mein-lidl-connect/mein-tarif/uebersicht.html"));
request1.CookieContainer = container;
var webResponse = await request1.GetResponseAsync();
var response = (HttpWebResponse)webResponse;
// Get the stream associated with the response.
Stream receiveStream = response.GetResponseStream();
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
var html = readStream.ReadToEnd();
CookieContainer = container;
requestStream.Dispose();
response.Dispose();
readStream.Dispose();
webResponse.Dispose();
}
But with this I only get the html from the Login page... It seems that i am using the cookiecontainer wrong.
So I got from Fiddler this Information (I Changed my LoginData Username=xxxxxxxxxxx; Password XXXXXXXXXXXX):
POST ttps://kundenkonto.lidl-connect.de/login.html HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, /
Referer: ttps://kundenkonto.lidl-connect.de/login.html
Accept-Language: de-DE
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate, br
Host: kundenkonto.lidl-connect.de
Content-Length: 109
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: resolution=1440; PHPSESSID=td1ee0rkkv7qr72ku6ilk1gq55
lastpage=1&REQUEST_TOKEN=51ae54e320c2cc7aa64302be163a0c5a&msisdn_msisdn=xxxxxxxxxxx&password=XXXXXXXXXXXX
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text / html, application / xhtml + xml, image / jxr");
client.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding","gzip, deflate");
client.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Language"," de-DE");
client.DefaultRequestHeaders.TryAddWithoutValidation("User - Agent", "Mozilla / 5.0(Windows NT 10.0; Win64; x64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 52.0.2743.116 Safari / 537.36 Edge / 15.15063");
maybe someone can help me:)
Thank You :)