Can i pass a Model from view to controller without Form? - c#

Hi guys i have difficulties of passing my model to controller> I wonder if this is a good practice or is it possible to do so. Here's what i want to achieve.
<% foreach (DownloadFile file in Model){ %>
click here to download
<% } >%
I want to pass the DownloadFile Object "file" to my controller that goes like this:
public ActionResult DownloadLabTestResult(DownloadFile File)
{
DownloadFile file = File;
...
return new FileStreamResult(Response.OutputStream, Response.ContentType);
}
I tried passing a string or integer and its doable. but when i want to pass an object like the above, i get a null value. What's the proper way to do this? thank u!

When using FileStreamResult, you need to give it the stream that represents the contents of the file, which will be consumed and sent to the client. Currently you've instead given it the ASP.NET response stream instead. It can't possibly read from that (it is an output-only stream).
So; where is the contents? Open up a stream to that and pass it in. Depending on your implementation, this could mean the local file-system, a network file-system, a database, a remote http (etc) server, or something generated in-memory (typically via MemoryStream).
Equally, it is for you to tell MVC what the content-type is; you shouldn't use the value from Response.*, since that is what you are constructing.

Related

ASP .NET Web API reading inputstream twice

I am using ASP .NET Web API and I have a Controller that have code similar to this:
[Route("UpdateData")]
[HttpPost]
public HttpResponseMessage UpdateData([FromBody]RequestClasses.UpdataData data)
{
string json;
if (HttpContext.Current.Request.InputStream.Length > 0)
{
HttpContext.Current.Request.InputStream.Position = 0;
using (var inputStream = new StreamReader(HttpContext.Current.Request.InputStream))
{
json = inputStream.ReadToEnd();
}
}
// Dencrypt json
return Request.CreateResponse(HttpStatusCode.OK);
}
As input parameter I have "[FromBody]RequestClasses.UpdataData data". I have this in order to be able to show a Help page (using Microsoft.AspNet.WebApi.HelpPage).
The data object received in this method is encrypted and I need to decrypt it.
My problem is that I cannot call HttpContext.Current.Request.InputStream because the "[FromBody]RequestClasses.UpdataData data" has disposed my InputStream.
Any good ideas to solve this? As I still need the help page to show which parameters to call the method with.
By design ASP.NET Web API can only read the payload input stream once. So, if the parameter binder reads it, you don't have it available. That's way people is telling you in the comments to use parameterless methods, and read the payload yourself.
However, you want to have parameters to see them in the help page. There is a solution for that: do the decryption of the request in previous steps. To do that you can use Message handlers. Please, see this: Encrypt Request/Reponse in MVC4 WebApi

How to Upload File along with some complex type in ASP.NET WebAPI

I have a requirement, where I have to upload file using WEB API. So created a api controller for Post and handled the Multi-part form data and I could successfully upload the files. But I need to pass an complex type with properties such as FileName, Description, FormId, etc... along with the file. So how to achieve this using single Post Controller. For eg.)
public HttpResponseMessage Post([FromBody] MyComplexType myType)
{
//Here I get the files from Request.Content.ReadAsAsyncStream();
// myType is always null.
}
Also from Client Side (Javascript and .NET Client) I can post either Mutlipart Formdata or the Complex type. But I need to do both in same request.
Please help....
Have you looked into using MultipartFormDataProvider where the request is a multipart request having 'formurlencoded' data + files?...but if your request is like 'json' data + files, then you can use MultipartMemoryStreamProvider...if files are huge and memory usage is a concern, you can create a custom MultipartStreamProvider...

Using WebClient to pass arrays as part of message body for post action

I am writing a console application that needs to perform a POST to an MVC controller. I am using the WebClient class to perform the POST. But I'm having trouble understanding how to add arrays to the message body.
For simple parameters, it seems to work if I do this:
using (var client = new WebClient())
{
var values = new NameValueCollection
{
{ "userName", "userName" },
{ "password", "passwordGoesHere"}
};
byte[] responseArray = client.UploadValues(String.Format("{0}/Mobile/StartSession", serverAddress), values);
Debug.WriteLine(String.Format("\r\nResponse received was :\n{0}\n", Encoding.ASCII.GetString(responseArray)));
}
I was trying to find how to pass arrays in the message body when using WebClient (for calling one of the other methods). I came across this solution: POST'ing arrays in WebClient (C#/.net)
It appears the solution actually passes parameters in the query string (and not in the message body). This seems to work in any case, as the HttpPost method on the MVC controller is still receiving the correct information. However, another method requires that I pass an image as an array of bytes. This is too large to be passed in the querystring and so the call fails.
So my question is, using the code I provided above, how can I add arrays in there as well. So an array of bytes for example, but also an array of strings.
If any one can provide me with a solution it would be much appreciated, or if I'm incorrect in my thinking please let me know.
Thanks
Instead of using array of bytes maybe you should POST a file in the same way files are uploaded from browser from file inputs. This way you will save some transfered bytes, but you have to use HttpWebRequest instead of WebClient. More about this solution is here:
Upload files with HTTPWebrequest (multipart/form-data)
You upload bytes as "multipart/form-data" content type. On the server you will receive the streams of bytes in Request.Files collection.

ASP MVC How to pass in-memory byte stream to Java Applet?

I need to pass an image (currently a byte stream) to a Java Applet in an ASP MVC 3.0 web site.
The docs for the applet says the file can be generated dynamically by a HTTP GET.
What should the Controller action that gets the dynamic content return?
Also, how do I specify the Url in the Html for the applet?
I've tried returning a File result from the controller, and embedding a "Html.RenderAction" call where the file name should go, but I get this error (on the Html fragment included below)
CS1502: The best overloaded method match for
'System.Web.WebPages.WebPageExecutingBase.Write(System.Web.WebPages.HelperResult)'
has some invalid arguments
HTML fragment
<param name="Filename" value="#Html.RenderAction("DownLoadImage", "Document", new { DocumentId = Model.DocumentId, Page = Model.Page })">
Controller Action
public ActionResult DownloadImage(string DocumentId, int PageNo)
{
byte[] bytes = documentProvider.GetImage(DocumentId, PageNo);
return File(bytes, "image/tiff");
}
The DownloadImage action works when I use it in a "download image" ActionLink.
Please let me know if you need anything else.
Apologies if I'm doing something dumb, or missing something very obvious. I know very little about Web Development, this is my first ASP MVC application, and the first time I've used a Java Applet . . . please be gentle
Thanks.
The synatx error is from Razor -- it renders differently than the old WebForms viewmodels which is used the Writer. But that is a bit of a red herring here -- you actually don't want to do it this way anyhow -- this is trying to drop the bytes of image data you are streaming into the HTML.
What I think you want to do is pass the applet a URL to the controller action that is rendering the image. It will read it off the wire then do it's thing. Your code should probably look like:
<param name="Filename" value="#Url.Action("DownLoadImage", "Document", new { DocumentId = Model.DocumentId, Page = Model.Page })">
Have no seat time with the applet so I'm not sure if that will do the trick. You might need to make it an absolute URI, or you might have some challenges with authentication depending on how things work under the hood.

Server side include external HTML?

In my asp.net-mvc application I need to include a page that shows a legacy page.
The body of this page is created by calling an existing Perl script.
This Perl script is externally hosted.
Is there a way to do something like this:
<!-- #Include virtual="http://www.example.com/theScript.plx"-->
Not as a direct include, because ASP.NET server-side-includes require the page to be compiled at the server.
You could use jQuery to download the HTML from that URL when the page loads, though I appreciate that's not perfect.
Alternatively (and I have no idea whether this will work) you could perform a WebRequest to the perl webpage from your ASP.NET MVC controller, and put the resulting HTML in the view as text. That way you could make use of things like output caching to limit the hits to the perl page if it doesn't change often.
If you wanted to do it all in one go, you could do an HTTP Request from the server and write the contents to the page?
Something like this:
Response.Write(GetHtmlPage("http://www.example.com/theScript.plx"));
Calling this method:
public String GetHtmlPage(string strURL)
{
// the html retrieved from the page
String strResult;
WebResponse objResponse;
WebRequest objRequest = System.Net.HttpWebRequest.Create(strURL);
objResponse = objRequest.GetResponse();
// the using keyword will automatically dispose the object
// once complete
using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
{
strResult = sr.ReadToEnd();
// Close and clean up the StreamReader
sr.Close();
}
return strResult;
}
(Most code ripped blatantly from here and therefore not checked)
You could implement this in a low-key fashion by simply using a frame and setting the frame source to the url that needs to be included. This is quite simple and can be down without any server or client side scripting, so that'd be my preferred approach, if possible.
If you want the html to appear to come from your server, however, you'll need to manually include it - typically by using WebRequest as Neil says. You may wish to cache the remote page for performance, though, since it's a perl script, I'll assume the page is dynamic, so this might not be a great idea.

Categories