how to convert a string passed in a constructor to Uri? - uri

i have a piece of code in C#. I am using a string as parameter in the constructor to give the filepath then I want to convert it into Uri to interact with the rest of the code in a different class.
How can i do that? Can anyone tell the syntax?
public string m_DTBook_FilePath;
public DTBooktoXukConversion(string bookfile)
{
m_DTBook_FilePath = bookfile;
Uri uri = new Uri(m_DTBook_FilePath);
}
Whats wrong in this syntax?

There's nothing wrong with that syntax. What's going wrong when you try it?
Note that in the snippet you've given, you don't do anything with the Uri after constructing it - if the problem is that later you're trying to use m_DTBook_FilePath as a Uri, then you should actually have:
public Uri m_DTBook_FilePath;
public DTBooktoXukConversion(string bookfile)
{
m_DTBook_FilePath = new Uri(bookfile);
}
(I would strongly recommend against having a public field in your real code, by the way.)

Related

Access .aspx page properties/variable from separate .cs file

Maybe a stupid question. C# 6.0 allows for string replacement using this syntax: $"string content {foo} {bar}". I would like to imitate this behavior in a class I've written for strings passed to it by default. The problem is that I am not sure how to access the public properties/variables. I am not sure if there is a way to access the properties using reflection or by passing this or this.Page to the constructor.
Figured it out:
public static object GetPropValue(object src, string propName)
{
return src.GetType().GetProperty(propName).GetValue(src, null);
}
object UID = GetPropValue(System.Web.HttpContext.Current.Handler, "UID");

How do QueryString parameters get bound to Action method parameters?

I have a webforms project, and am attempting to run some code that allows me to make a call to an MVC route and then render the result within the body of the web forms page.
There are a couple of HttpResponse/Request/Context wrappers which I use to execute a call to an MVC route, e.g.:
private static string RenderInternal(string path)
{
var responseWriter = new StringWriter();
var mvcResponse = new MvcPlayerHttpResponseWrapper(responseWriter, PageRenderer.CurrentPageId);
var mvcRequest = new MvcPlayerHttpRequestWrapper(Request, path);
var mvcContext = new MvcPlayerHttpContextWrapper(Context, mvcResponse, mvcRequest);
lock (HttpContext.Current)
{
new MvcHttpHandlerWrapper().PublicProcessRequest(mvcContext);
}
...
The code works fine for executing simple MVC routes, for e.g. "/Home/Index". But I can't specify any query string parameters (e.g. "/Home/Index?foo=bar") as they simply get ignored. I have tried to set the QueryString directly within the RequestWrapper instance, like so:
public class MvcPlayerHttpRequestWrapper : HttpRequestWrapper
{
private readonly string _path;
private readonly NameValueCollection query = new NameValueCollection();
public MvcPlayerHttpRequestWrapper(HttpRequest httpRequest, string path)
: base(httpRequest)
{
var parts = path.Split('?');
if (parts.Length > 1)
{
query = ExtractQueryString(parts[1]);
}
_path = parts[0];
}
public override string Path
{
get
{
return _path;
}
}
public override NameValueCollection QueryString
{
get
{
return query;
}
}
...
When debugging I can see the correct values are in the "request.QueryString", but the values never get bound to the method parameter.
Does anyone know how QueryString values are used and bound from an http request to an MVC controller action?
It seems like the handling of the QueryString value is more complex than I anticipated. I have a limited knowledge of the internals of the MVC Request pipeline.
I have been trying to research the internals myself and will continue to do so. If I find anything I will update this post appropriately.
I have also created a very simple web forms project containing only the code needed to produce this problem and have shared it via dropbox: https://www.dropbox.com/s/vi6erzw24813zq1/StackMvcGetQuestion.zip
The project simply contains one Default.aspx page, a Controller, and the MvcWrapper class used to render out the result of an MVC path. If you look at the Default.aspx.cs you will see a route path containing a querystring parameter is passed in, but it never binds against the parameter on the action.
As a quick reference, here are some extracts from that web project.
The controller:
public class HomeController : Controller
{
public ActionResult Index(string foo)
{
return Content(string.Format("<p>foo = {0}</p>", foo));
}
}
The Default.aspx page:
protected void Page_Load(object sender, EventArgs e)
{
string path = "/Home/Index?foo=baz";
divMvcOutput.InnerHtml = MvcWrapper.MvcPlayerFunctions.Render(path);
}
I have been struggling with this for quite a while now, so would appreciate any advice in any form. :)
MVC framework will try to fill the values of the parameters of the action method from the query string (and other available data such as posted form fields, etc.), that part you got right. The part you missed is that it does so by matching the name of the parameter with the value names passed in. So if you have a method MyMethod in Controller MyController with the signature:
public ActionResult MyMethod(string Path)
{
//Some code goes here
}
The query string (or one of the other sources of variables) must contain a variable named "Path" for the framework to be able to detect it. The query string should be /MyController/MyMethod?Path=Baz
Ok. This was a long debugging session :) and this will be a long response, so bear with me :)
First how MVC works. When you call an action method with input parameters, the framework will call a class called "DefaultModelBinder" that will try and provide a value for each basic type (int, long, etc.) and instance of complex types (objects). This model binder will depend on something called the ValueProvider collection to look for variable names in query string, submitted forms, etc. One of the ValueProviders that interests us the most is the QueryStringValueProvider. As you can guess, it gets the variables defined in the query string. Deep inside the framework, this class calls HttpContext.Current to retrieve the values of the query string instead of relying on the ones being passed to it. In your setup this is causing it to see the original request with localhost:xxxx/Default.aspx as the underlying request causing it to see an empty query string. In fact inside the Action method (Bar in your case) you can get the value this.QueryString["variable"] and it will have the right value.
I modified the Player.cs file to use a web client to make a call to an MVC application running in a separate copy of VS and it worked perfectly. So I suggest you run your mvc application separately and call into it and it should work fine.

MultiPart Request RenameFilePolicy

I am trying to avoid some naming conflicts in my uploaded files (I used com.oreilly.servlet.MultipartRequest ).
At this moment my constructor looks like this:
MultipartRequest multi = new MultipartRequest(request, uploadPath);
I would like to implement the constructor with FileRenamePolicy in order to rename my file with a value taken from a form (something like request.getParameterValue("title");
I think I should use the foloowing constructor? But I don't know how to set the "policy" paramter
MultipartRequest(javax.servlet.http.HttpServletRequest request,
java.lang.String saveDirectory,
int maxPostSize,
java.lang.String encoding,
FileRenamePolicy policy)
Do you have any suggestions?
Thanks!
You should implement a custom FileRenamePolicy which gives you the File appending the title sent along with the request.
Here is what you are looking for:
private static class MyTitleRenamePolicy extends FileRenamePolicy {
java.io.File rename(java.io.File f) {
return new File(f.getParentFile(),
rename.getName() + "_"+ request.getParameter("title"));
}
}
new MultipartRequest(request, saveDirectory, maxPostSize, encoding,
new MyTitleRenamePolicy(request));

Better way to get Page Name

I'm using this to get the current page name..so this returns for example MyPage.aspx
public string GetCurrentPageName()
{
string urlPath = Request.Url.AbsolutePath;
FileInfo fileInfo = new FileInfo(urlPath);
string pageName = fileInfo.Name;
return pageName;
}
There has to be an easier way? Meaning there's got to be an existing method or property in the .NET framework one would think.
The way I interpret the question, what you're looking for is an efficient way of retrieving the name of the currently executing aspx page, i.e. System.Web.UI.Page.
If that is true you shouldn't have to deal with any FileInfo objects or hit the filesystem. Simply use the AppRelativeVirtualPath property on the page object:
using System;
using System.IO;
using System.Web.UI;
namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string pageName = Path.GetFileNameWithoutExtension(Page.AppRelativeVirtualPath);
}
}
}
If you want to get the fully-qualified (or "rooted") path of your currently executing page you can use Server.MapPath like this:
string path = Server.MapPath(Page.AppRelativeVirtualPath);
Using AppRelativeVirtualPath has the benefit of working even when you're using URL rewriting and, since it doesn't use Request.Url (which is provided by your users), you don't have to worry about potentially malicious data.
Would HttpContext.Current.CurrentHandler be what you're looking for?
Since you're more interested in the physical file name vs the page object something along the lines of
var page = (Page) HttpContext.Current.CurrentHandler;
string url = page.AppRelativeVirtualPath;
This along with the information from #Markus Olsson can give you access to the page in any point during its execution even if you're outside of page class.
I use Request.Url.Segments.Last() , which I think is elegant enough.
just for interest I did little search with intellisence. did not found any property. still same logic in other way round.
string currentPageName = System.IO.Path.GetFileName(Request.Url.AbsolutePath);
As was pointed out in one of the answers to this earlier question of yours, I'd go for an option that didn't need me to create a FileInfo object.
There isn't always a direct mapping between a requested page and a file system object, especially when routing/url rewriting etc comes in to play.
Dim MyPage As String = Path.GetFileName(Page.AppRelativeVirtualPath.ToString).ToString
This one works for me
Not much better, but you could try this extension method:
public static string GetPageName(this Page myPage)
{
FileInfo fi =new FileInfo(myPage.MapPath(myPage.AppRelativeVirtualPath));
return fi.Name;
}
and just call it in your page's "OnInit" or whatever method as:
string pageName = this.GetPageName();
Marc
System.IO.Path.GetFileName(Request.PhysicalPath)

best way to store / lookup name value pairs

I have a list of error codes I need to reference, kinda like this:
Code / Error Message
A01 = whatever error
U01 = another error
U02 = yet another error type
I get the Code returned to me via a web service call and I need to display or get the readable error. So I need a function when passed a Code that returns the readable description. I was just going to do a select case but thought their might be a better way. What is the best way / most effieient way to do this?
Use a Dictionary, (in C#, but the concept and classes are the same):
// Initialize this once, and store it in the ASP.NET Cache.
Dictionary<String,String> errorCodes = new Dictionary<String,String>();
errorCodes.Add("A01", "Whatever Error");
errorCodes.Add("U01", "Another Error");
// And to get your error code:
string ErrCode = errorCodes[ErrorCodeFromWS];
You would use a dictionary. A dictionary uses a hashmap internally for performance, so it is good in that regard. Also, because you want this to go as quickly as possible by the sounds of it, I would statically initialize it in its own class instead of, for example, in an XML file or slimier. You would probably want something like:
public static class ErrorCodes
{
private static Dictonary<string, string> s_codes = new Dicontary<string, string>();
static ErrorCodes()
{
s_codes["code"] = "Description";
s_codes["code2"] = "Description2";
}
public static string GetDesc(string code)
{
return s_codes[code];
}
}
That way, if you wanted to move the back end to a file instead of being static, then you could.

Resources