HttpClient copy data from Request.Form .NET Core - .net-core

I have POST query with Form data with files and I need to send the same data to another POST request.
I'm going to use for this HttpClient class.
Is there a way to copy all Request.Form data and insert them to new request? Or I need to add every param?
I mean something like this:
var httpClient = new HttpClient();
var httpResponseMessage = await httpClient.PostAsync("some_url", Request.Form);

Is there a way to copy all Request.Form data and insert them to new request? Or I need to add every param?
You need to add every param like below:
Model in ProjectA:
public class FormData
{
public int Id { get; set; }
public IFormFile File { get; set; }
public string Name { get; set; }
}
View in ProjectA:
#model FormData
<form asp-action="Post" enctype="multipart/form-data">
<div>
Id:<input asp-for="Id"/>
</div>
<div>
Name:<input asp-for="Name"/>
</div>
<div>
FIle:<input asp-for="File" />
</div>
<div>
<input type="submit" value="create" />
</div>
</form>
Controller in ProjectA:
[HttpPost]
public async Task<IActionResult> Post(FormData formData)
{
HttpClient client = new HttpClient();
// var formData = HttpContext.Request.Form;
client.BaseAddress = new Uri("http://localhost:63331");//your applicationUrl
client.DefaultRequestHeaders.Accept.Clear();
var multiContent = new MultipartFormDataContent();
var file = formData.File;
if (file != null)
{
var fileStreamContent = new StreamContent(file.OpenReadStream());
multiContent.Add(fileStreamContent, "File", file.FileName);
}
multiContent.Add(new StringContent(formData.Id.ToString()), "id");
multiContent.Add(new StringContent(formData.Name.ToString()), "name");
var response = await client.PostAsync("/api/values", multiContent);
//do your stuff...
return Ok();
}
Model in ProjectB:
public class FormDataModel
{
public int Id { get; set; }
public IFormFile File { get; set; }
public string Name { get; set; }
}
Controller in ProjectB:
[HttpPost]
public void Post([FromForm]FormDataModel model)
{
//...
}
Result:

Related

<response xmlns=''> was not expected

I'm integrating with BigBlueButton API with Asp Net MVC. But I can't read the response xml file back from api .
It's a force module project.
My code:
public ActionResult GetMeetings()
{
List<AllMeetings> allMeetings = new List<AllMeetings>();
XmlSerializer serializer = new XmlSerializer(typeof(List<AllMeetings>), "response");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://bbb.hsu.ac.ir/bigbluebutton/api/getMeetings?checksum=aca692f682f06312cb43f14564ddf96cb76925ed");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream dataStream = response.GetResponseStream();
StreamReader sr = new StreamReader(dataStream);
List<AllMeetings> allMeeting =(List<AllMeetings>)serializer.Deserialize(sr);
return View(allMeeting);
}
I coded a class so that I could define attributes as xml element and I use them as an enumerable model
namespace BBBJavaScriptTest
{
[Serializable]
[XmlType("response")]
public class AllMeetings
{
[XmlElement(ElementName = "meetingName")]
public string meetingName { get; set; }
[XmlElement(ElementName = "meetingID")]
public string meetingID { get; set; }
[XmlElement(ElementName = "createDate")]
public string createDate { get; set; }
[XmlElement(ElementName = "voiceBridge")]
public string voiceBridge { get; set; }
[XmlElement(ElementName = "moderatorPW")]
public string moderatorPW { get; set; }
public AllMeetings()
{
}
}
and the view part is Razor View:
#model IEnumerable<AllMeetings>
#{
ViewBag.Title = "GetMeetings";
Layout = null;
}
<h2>GetMeetings</h2>
<table class="table table-bordered">
<tr>
<td>meetingID</td>
<td>meetingName</td>
<td>createDate</td>
<td>voiceBridge</td>
<td>moderatorPW</td>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#item.meetingID</td>
<td>#item.meetingName</td>
<td>#item.createDate</td>
<td>#item.voiceBridge</td>
<td>#item.moderatorPW</td>
</tr>
}
</table>
Response sample:
<response>
<returncode>SUCCESS</returncode>
<meetings>
<meeting>
<meetingName>****</meetingName>
<meetingID>****</meetingID>
<internalMeetingID>
****
</internalMeetingID>
<createTime>1603543982183</createTime>
<createDate>Sat Oct 24 16:23:02 IRST 2020</createDate>
<voiceBridge>78409</voiceBridge>
<dialNumber>****</dialNumber>
<attendeePW>ap</attendeePW>
<moderatorPW>mp</moderatorPW>
<running>true</running>
<duration>400</duration>
<hasUserJoined>true</hasUserJoined>
<recording>false</recording>
<hasBeenForciblyEnded>false</hasBeenForciblyEnded>
<startTime>1603543982435</startTime>
<endTime>0</endTime>
<participantCount>1</participantCount>
<listenerCount>1</listenerCount>
<voiceParticipantCount>0</voiceParticipantCount>
<videoCount>0</videoCount>
<maxUsers>0</maxUsers>
<moderatorCount>1</moderatorCount>
<attendees>
<attendee>
<userID>****</userID>
<fullName>****</fullName>
<role>MODERATOR</role>
<isPresenter>true</isPresenter>
<isListeningOnly>true</isListeningOnly>
<hasJoinedVoice>false</hasJoinedVoice>
<hasVideo>false</hasVideo>
<clientType>HTML5</clientType>
</attendee>
</attendees>
<metadata> </metadata>
<isBreakout>false</isBreakout>
</meeting>
</meetings>
</response>
I solved the problem , And here is the solution :
XDocument doc = XDocument.Load(sr);
List<AllMeetings> meetings = new List<AllMeetings>();
foreach (XElement element in doc.Element("response").Elements("meetings").Elements("meeting"))
{
AllMeetings newMeeting = new AllMeetings();
newMeeting.meetingName = (string)element.Element("meetingName");
meetings.Add(newMeeting);
}
return View(meetings);

Display Image of IFormFile saved as Byte in database

This is my code in ASP.NET CORE 3.0, when I save the image using type as IFormFile in View Model and as Byte in model. Now I want to retrieve this image in Edit Method. I am Unable to display image. Here is my code
var formData = new Student()
{
AppUserID = userId,
FirstName = model.FirstName,
MatricMarks = model.MatricMarks,
CollegeName = model.CollegeName,
HSSCMarks = model.HSSCMarks,
};
if (model.Profile != null && model.Profile.FileName != "" && model.Profile.FileName != null)
{
IFormFile file = model.Profile;
if (file.Length > 0)
//Convert Image to byte and save to database
{
using (var stream = new MemoryStream())
{
await file.OpenReadStream().CopyToAsync(stream);
formData.Profile = stream.ToArray();
}
}
}
ViewModel
public class StudentSignUpViewModel
{
public string Username { get; set; }
public string CollegeName { get; set; }
public string HSSCMarks { get; set; }
public IFormFile Profile { get; set; }
}
here is Model class
public string MatricMarks { get; set; }
public string CollegeName { get; set; }
public string HSSCMarks { get; set; }
[Required]
public byte[] Profile { get; set; }
And here is Edit[GET] Method where Im trying to display image, please guide what went wrong
public IActionResult Edit(int? id)
{
StudentSignUpViewModel model = new StudentSignUpViewModel();
if (id == null)
{
return NotFound();
}
var student = _context.Students.Where(x => x.StudentId == id.Value).Include(x=>x.AppUser).FirstOrDefault();
model.MatricMarks = student.MatricMarks;
model.CollegeName = student.CollegeName;
model.HSSCMarks = student.HSSCMarks;
model.CoursesArray = student.Courses;
var base64 = Convert.ToBase64String(student.Profile);
ViewBag.imgSrc = string.Format("data:image/jpg;base64,{0}",model.Profile, base64);
}
View Method where I'm Trying to display image
<div class="form-group">
<img src="#ViewBag.imgSrc" class="profile-user-img img-responsive img-circle" alt="User profile picture" />
<label asp-for="Username" class="control-label"></label>
<input asp-for="Username" class="form-control" />
Note: Irrelevant Code is cut out.
To display binary image using base64 string, please modify your code as below.
var base64 = Convert.ToBase64String(student.Profile);
ViewBag.imgSrc = string.Format("data:image/jpg;base64,{0}", base64);
Besides, you can also save these image file(s) on your web server rather than storing them in database, so that your app can serve these images directly to clients.
For more information about serving static files, please check: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-3.1

Web API Post giving me error

I have a web API application. I'm supposed to do a post to an endpoint. When l tried my API controller in postman, l get the error message "
Requested resource does not support HTTP 'POST'
I'm new to Web API so any help and suggestions are welcomed.
This is my model class:
namespace Products.Models
{
public class Prouct
{
public string ProductID { get; set; }
public string ProductName { get; set; }
public string ProductPrice { get; set; }
public string VoucherID { get; set; }
}
}
Here is my controller class
[RoutePrefix("api/products")]
public class ProductsController : ApiController
{
static HttpClient client = new HttpClient();
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
public string Get(int id)
{
return "value";
}
[Route("products")]
public async Task PostAsync(string ProductID, string ProductName, string ProductPrice,
string VoucherID)
{
Products p = new Products();
p.ProductID = ProductID;
p.ProductName = ProductName;
p.ProductPrice = ProductPrice;
p.VoucherID = VoucherID;
var client = new HttpClient { BaseAddress = new
Uri("http://localhost:51613/") };
var response = await
client.PostAsJsonAsync("api/products",
p);
if (response.IsSuccessStatusCode)
{
}
public void Put(int id, [FromBody]string value)
{
}
public void Delete(int id)
{
}
You need to specify HttpPost on PostAsync method. by default, it is [HttpGet].
[HttpPost]
[Route("products")]
public async Task PostAsync(string ProductID, string ProductName, string ProductPrice, string VoucherID)
{
// implementation
}
Looks like you're stuck in a loop. Why does the PostAsync method call itself after having been invoked? This will result in an endless request loop.
var client = new HttpClient { BaseAddress = new Uri("http://localhost:51613/") };
This is not related to the fact that the [HttpPost] attribute is required however.
Please observe that you are supposed to use [FromBody] . Also inside Postman (image attached) you have to choose "Raw" data with the product json with type as JSON(application.json).
[HttpPost]
[Route("products")]
public async Task PostAsync([FromBody] Products p)
{
var client = new HttpClient
{
BaseAddress = new
Uri("http://localhost:51613/")
};
var response = await
client.PostAsJsonAsync("api/products",
p);
if (response.IsSuccessStatusCode)
{
}
}

How to send data from view to controller action in asp.net mvc?

I developed a custom HtmlHelper extension method but that data is not
posting Action.
HtmlHelper extension class:
public static class TestHtmlHelper
{
public static MvcHtmlString CreateControl(this HtmlHelper helper, string tagName, IDictionary<string, string> attributes)
{
var newTag = new TagBuilder(tagName);
newTag.MergeAttributes(attributes, true);
return MvcHtmlString.Create(newTag.ToString(TagRenderMode.Normal));
}
public static string Image(this HtmlHelper helper, string id, string url, string alternateText, object htmlAttributes)
{
// Create tag builder
var builder = new TagBuilder("img");
// Create valid id
builder.GenerateId(id);
// Add attributes
builder.MergeAttribute("src", url);
builder.MergeAttribute("alt", alternateText);
builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));
// Render tag
return builder.ToString(TagRenderMode.Normal);
}
}
//View code
#using (Html.BeginForm("Go","Home",FormMethod.Post))
{
IDictionary<string, string> d = new Dictionary<string, string>();
d.Add("type", "text");
d.Add("id", "text1");
d.Add("required", "required");
#Html.Raw(Html.CreateControl("input", d))
#Html.Raw(Html.Image("image1", "/Images/bullet.png", "bullet", new { border = "4px" }))
d = null;
d = new Dictionary<string, string>();
d.Add("type", "submit");
d.Add("value", "Go");
#Html.Raw(Html.CreateControl("input", d))
<span></span>
d = null;
d = new Dictionary<string, string>();
d.Add("value", "text");
d.Add("id", "span1");
d.Add("text", "required");
#Html.Raw(Html.CreateControl("span", d))
}
// Controller code
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
return View();
}
[HttpPost]
public ActionResult Go(string test)
{
return Content(test);
}
I didn't get data in string test. I want to submit that data to DB.
To get input values as parameters for an MVC action, you need to include NAME for the input types.
I do not see NAME for any input types in your code.
Also I do not see TEST in your code
For example, if your form is -
#using (Html.BeginForm("Submit","Ajax",FormMethod.Post))
{
<input type="text" name="Rami"/>
<input type="submit" value="Go"/>
}
Output ScreenShot -
Put your inputs inside a form tag. All the input data will be sent to the controller on form submit. Please see the example:
View:
#using (Html.BeginForm("Search", "Events"))
{
#Html.TextBox("name")
<input type="submit" value="Search" />
}
Controller:
public class EventsController: Controller
{
public ActionResult Search(string name)
{
//some operations goes here
return View(); //return some view to the user
}
}
If you need to work with more complex types just lern how to use models in ASP.NET MVC. Here is short example:
Razor:
#model UserModel
#using (Html.BeginForm("Search", "Events"))
{
#Html.TextBoxFor(m => m.FirstName)
#Html.TextBoxFor(m => m.LastName)
<input type="submit" value="Search" />
}
Controller:
public class EventsController: Controller
{
public ActionResult Search(UserModel model)
{
//some operations goes here
return View(); //return some view to the user
}
}
Model (C#):
public class UserModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

Error loading images from database

I have a question about showing images loaded from a mysql database in an Index view.
In my database table "deliverables" I have "item_id", "deliverable_image" and "afstudeerrichting_id". "item_id" and "afstudeerrichting_id" are FK from other tables.
I want to show the images when afstudeerrichting_id = ..
Controller:
public ActionResult Index()
{
var model = repository.GetIdsOfImages(1);
return View(model.ToList());
}
public ActionResult ShowImage(int id)
{
IQueryable<byte[]> data = repository.GetImages(id);
byte[] firstimage = data.First();
return File(firstimage, "image/png");
}
Repository:
public IQueryable<long> GetIdsOfImages(int afstudeerrichtingid)
{
return from deliverable in entities.deliverables
where deliverable.afstudeerichting_id.Equals(afstudeerrichtingid)
select deliverable.item_id;
}
public IQueryable<byte[]> GetImages(int itemID)
{
return from deliverable in entities.deliverables
where deliverable.item_id.Equals(itemID)
select deliverable.deliverable_image;
}
View:
#foreach(var imgID in Model.DeliverablesIDsList)
{
<img src="#Url.Action("ShowImage", "Deliverable", new { DeliverableID = imgID })" />
}
In my Viewmodel I have:
public List<long> DeliverablesIDsList { get; set; }
public int DeliverableID { get; set; }
But now I always get this error:
he model item passed into the dictionary is of type 'System.Collections.Generic.List`1[System.Int64]', but this dictionary requires a model item of type 'GDMfrontEnd.Models.DeliverableViewModel'.
Does someone knows what I'm doing wrong?
you're sending to the view a list of int64 repository.GetIdsOfImages(1).ToList() and the view requires a DeliverableViewModel, so you must create a model and put the list into the model and send it to the view
the action should looks like:
public ActionResult Index()
{
var model = repository.GetIdsOfImages(1);
DeliverableViewModel model = new DeliverableViewModel()
model.DeliverablesIDsList = repository.GetIdsOfImages(1).ToList();
return View(model); //send to the view a model type of DeliverableViewModel
}
now with ActionResult ShowImage, the action expect id parmeter and you're sending DeliverableID, so change de var name
public ActionResult ShowImage(int DeliverableID)
{
IQueryable<byte[]> data = repository.GetImages(DeliverableID);
byte[] firstimage = data.First();
return File(firstimage, "image/png");
}

Resources